Skip to content

Do not hardcode char/bytes having 8 bits #917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2022

Conversation

tautschnig
Copy link
Collaborator

@tautschnig tautschnig commented May 13, 2017

The C standard does not guarantee that char is exactly 8 bits, and there are DSPs (such Texas Instruments C55x) that do not have 8-bit-bytes. Use the configuration value instead.

@tautschnig
Copy link
Collaborator Author

tautschnig commented May 23, 2017

Marking do-not-merge as it includes a commit that overlaps with #955.

@tautschnig tautschnig force-pushed the byte-config branch 3 times, most recently from d6010a2 to 4047f38 Compare May 23, 2017 17:43
@tautschnig tautschnig assigned kroening and unassigned tautschnig May 25, 2017
@tautschnig tautschnig force-pushed the byte-config branch 2 times, most recently from c5fb9c2 to ebc4c75 Compare June 28, 2017 14:16
@tautschnig tautschnig force-pushed the byte-config branch 2 times, most recently from ff0e2f6 to 437462a Compare July 15, 2017 18:22
@tautschnig tautschnig changed the base branch from master to develop August 22, 2017 12:25
@tautschnig tautschnig assigned tautschnig and unassigned kroening Sep 2, 2017
@tautschnig tautschnig changed the title Do not assume that chars/bytes have 8 bits (and some cleanup) [depends: #1331,#1332,#1333] Do not assume that chars/bytes have 8 bits (and some cleanup) Sep 2, 2017
@tautschnig tautschnig changed the title [depends: #1331,#1332,#1333] Do not assume that chars/bytes have 8 bits (and some cleanup) [depends: #1333] Do not assume that chars/bytes have 8 bits (and some cleanup) Sep 4, 2017
The C standard does not guarantee that char is exactly 8 bits, and there
are DSPs (such Texas Instruments C55x) that do not have 8-bit-bytes. Use
the configuration value instead.
@tautschnig tautschnig changed the title Do not hardcode char/bytes having 8 bits [depends-on: #6009] Do not hardcode char/bytes having 8 bits Oct 17, 2022
@tautschnig tautschnig marked this pull request as ready for review October 17, 2022 12:03
Copy link
Member

@peterschrammel peterschrammel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tautschnig created on 13 May 2017

Last one on the stack?

@@ -185,7 +187,7 @@ get_partitions_long(const std::size_t n, const std::size_t k)
/// Compute all positions of ones in the bit vector `v` (1-indexed).
std::vector<std::size_t> get_ones_pos(std::size_t v)
{
const std::size_t length = sizeof(std::size_t) * 8;
const std::size_t length = sizeof(std::size_t) * CHAR_BIT;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description states that you are using the width from the configuration. But this line is using the width for the machine for which cbmc is being compiled. Shouldn't config.ansi_c.char_width be used instead? The distinction could be important if cbmc is to be used for program written for a machine such as a DSP like you suggested in the PR desription. Wouldn't these architectures be more likely to be targeted using a cross compiler rather than porting cbmc to the target hardware itself?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right in that care is required where CHAR_BIT is the right choice and where config.ansi_c.char_width is to be used instead. I hope to have made the right choice in all places, but of course may have made mistakes. For this particular case: as far as I understand the code, this is about the width of bytes that CBMC is being compiled for, and not whatever the verification target might be. So I claim that CHAR_BIT is correct. Now you are also right in that, in all likelihood, one would use a cross compiler for such a DSP, and it may well be that no platform that CBMC ever runs on has CHAR_BIT != 8 - but I'd also like to avoid magic numbers, making it very difficult to tell whether the use of "8" is one that should be config.ansi_c.char_width instead, or is actually fine for it's the compile-time byte width on all relevant platforms.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are convinced that we are depending on the right thing in this case, then I am happy to merge this as is.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This specific case it is to enumerate various bit sequences, and this enumeration is done by the compiled CBMC binary.

@tautschnig
Copy link
Collaborator Author

tautschnig created on 13 May 2017

Last one on the stack?

🤣 You wish!

Copy link
Contributor

@thomasspriggs thomasspriggs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI - CHAR_BIT is the C standard library version of this constant. The C++ equivalent is std::numeric_limits<char>::digits. In this case digits refers to binary digits on the underlying hardware and std::numeric_limits<char>::radix is 2.

🤔 I am happy for debugging and addition of tests for a platform where char is not 8 bits to be left for a follow-up PR if and when this becomes a priority.

@@ -38,14 +39,14 @@ optionalt<mp_integer> member_offset(
{
const std::size_t w = to_c_bit_field_type(comp.type()).get_width();
bit_field_bits += w;
result += bit_field_bits / 8;
bit_field_bits %= 8;
result += bit_field_bits / config.ansi_c.char_width;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming we guarantee that char_width is always different than zero in all these cases, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, though we might one day want to have some architecture sanity check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be loaded from file through configt::set_from_symbol_table and symtab2gb. Therefore it could theoretically be set to 0 in the file and I am not sure we have appropriate validation that the value from file is not 0.

@tautschnig tautschnig merged commit baef5a3 into diffblue:develop Oct 18, 2022
@tautschnig tautschnig deleted the byte-config branch October 18, 2022 14:17
@@ -137,7 +137,7 @@ void is_fresh_baset::update_ensures(goto_programt &ensures)

array_typet is_fresh_baset::get_memmap_type()
{
return array_typet(c_bool_typet(8), infinity_exprt(size_type()));
Copy link
Collaborator

@remi-delmas-3000 remi-delmas-3000 Oct 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to propagate this to instrumentation code ? This code does not represent anything running on an actual processor. Should c_bool_typet(8) be deprecated completely ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with an arbitrary type, but we must not have "8" as a magic number. I assumed this was "8" in the first place so as to have byte granularity? Was I wrong?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My usual assumption is that architecture should be well defined at the point of running the front end. This is because the C front end runs an external C pre-processor which can have architecture specific macro expansions. As goto-instrument runs after the front end, it is operating on an architecture specific program form. Note for example that the c_bool_type() construction function in src/util/c_types.cpp references the same config field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants