How to declare bits in C? - c

I'm trying to do this :
uint64_t key = 0110000010110110011001101111101000111111111010001011000110001110;
Doesn't work. GCC says
warning: integer constant is too large for its type
Any idea why?

Although neither the draft C99 standard nor the draft C11 standard support binary literals, since you specifically mention gcc it has an extension for binary literals which says:
Integer constants can be written as binary constants, consisting of a sequence of ‘0’ and ‘1’ digits, prefixed by ‘0b’ or ‘0B’. This is particularly useful in environments that operate a lot on the bit level (like microcontrollers).
they gives the following example (see it live):
i = 0b101010;
and it looks like clang also support this as an extension as well (see it live):
[...]binary literals (for instance, 0b10010) are recognized. Clang supports this feature as an extension in all language modes.
This is not available in standard C++ either until C++14 [lex.icon].

Due to the leading 0 that's read as a very large octal literal, which is probably not what you want. Amazingly, C doesn't have binary literals.
As an extension, gcc supports binary literals with the 0b prefix, eg, 0b101010. If you don't want to rely on extensions, hexadecimal is probably the most reasonable alternative.

Use Hex decimal they are more compact and can represent binary example:
0x01 // This is 0001
0x02 // 0010
Using binary the way you want is particularly ugly inside someone's code.
Also starting a number with 0 (in your example) will be interpreted as octal.

To add to #Shafik's answer:
#include <inttypes.h>
#include <stdio.h>
int main(void)
{
uint64_t i = UINT64_C(
0b0110000010110110011001101111101000111111111010001011000110001110);
printf("%" PRIX64 "\n", i) ;
return 0;
}
Worked with: gcc -std=gnu99 - output: 60B666FA3FE8B18E
Really, embedded systems are much more strict about extensions, particularly if you're unfortunate enough to be required to adhere to standards like MISRA-C. Hexadecimal conversion is just the grouping of 4 binary digits to 0x0 -> 0xf.

I think that is because you exceeded the maximum integer that can be stored in an uint datatype.
Try using an array of boolean type.

Related

multi-character character constant [-Wmultichar]-warning error [duplicate]

Why is this a warning? I think there are many cases when is more clear to use multi-char int constants instead of "no meaning" numbers or instead of defining const variables with same value. When parsing wave/tiff/other file types is more clear to compare the read values with some 'EVAW', 'data', etc instead of their corresponding values.
Sample code:
int waveHeader = 'EVAW';
Why does this give a warning?
According to the standard (§6.4.4.4/10)
The value of an integer character constant containing more than one
character (e.g., 'ab'), [...] is implementation-defined.
long x = '\xde\xad\xbe\xef'; // yes, single quotes
This is valid ISO 9899:2011 C. It compiles without warning under gcc with -Wall, and a “multi-character character constant” warning with -pedantic.
From Wikipedia:
Multi-character constants (e.g. 'xy') are valid, although rarely
useful — they let one store several characters in an integer (e.g. 4
ASCII characters can fit in a 32-bit integer, 8 in a 64-bit one).
Since the order in which the characters are packed into one int is not
specified, portable use of multi-character constants is difficult.
For portability sake, don't use multi-character constants with integral types.
This warning is useful for programmers that would mistakenly write 'test' where they should have written "test".
This happen much more often than programmers that do actually want multi-char int constants.
If you're happy you know what you're doing and can accept the portability problems, on GCC for example you can disable the warning on the command line:
-Wno-multichar
I use this for my own apps to work with AVI and MP4 file headers for similar reasons to you.
Even if you're willing to look up what behavior your implementation defines, multi-character constants will still vary with endianness.
Better to use a (POD) struct { char[4] }; ... and then use a UDL like "WAVE"_4cc to easily construct instances of that class
Simplest C/C++ any compiler/standard compliant solution, was mentioned by #leftaroundabout in comments above:
int x = *(int*)"abcd";
Or a bit more specific:
int x = *(int32_t*)"abcd";
One more solution, also compliant with C/C++ compiler/standard since C99 (except clang++, which has a known bug):
int x = ((union {char s[5]; int number;}){"abcd"}).number;
/* just a demo check: */
printf("x=%d stored %s byte first\n", x, x==0x61626364 ? "MSB":"LSB");
Here anonymous union is used to give a nice symbol-name to the desired numeric result, "abcd" string is used to initialize the lvalue of compound literal (C99).
If you want to disable this warning it is important to know that there are two related warning parameters in GCC and Clang: GCC Compiler options -wno-four-char-constants and -wno-multichar

When should I use UINT32_C(), INT32_C(),... macros in C?

I switched to fixed-length integer types in my projects mainly because they help me think about integer sizes more clearly when using them. Including them via #include <inttypes.h> also includes a bunch of other macros like the printing macros PRIu32, PRIu64,...
To assign a constant value to a fixed length variable I can use macros like UINT32_C() and INT32_C(). I started using them whenever I assigned a constant value.
This leads to code similar to this:
uint64_t i;
for (i = UINT64_C(0); i < UINT64_C(10); i++) { ... }
Now I saw several examples which did not care about that. One is the stdbool.h include file:
#define bool _Bool
#define false 0
#define true 1
bool has a size of 1 byte on my machine, so it does not look like an int. But 0 and 1 should be integers which should be turned automatically into the right type by the compiler. If I would use that in my example the code would be much easier to read:
uint64_t i;
for (i = 0; i < 10; i++) { ... }
So when should I use the fixed length constant macros like UINT32_C() and when should I leave that work to the compiler(I'm using GCC)? What if I would write code in MISRA C?
As a rule of thumb, you should use them when the type of the literal matters. There are two things to consider: the size and the signedness.
Regarding size:
An int type is guaranteed by the C standard values up to 32767. Since you can't get an integer literal with a smaller type than int, all values smaller than 32767 should not need to use the macros. If you need larger values, then the type of the literal starts to matter and it is a good idea to use those macros.
Regarding signedness:
Integer literals with no suffix are usually of a signed type. This is potentially dangerous, as it can cause all manner of subtle bugs during implicit type promotion. For example (my_uint8_t + 1) << 31 would cause an undefined behavior bug on a 32 bit system, while (my_uint8_t + 1u) << 31 would not.
This is why MISRA has a rule stating that all integer literals should have an u/U suffix if the intention is to use unsigned types. So in my example above you could use my_uint8_t + UINT32_C(1) but you can as well use 1u, which is perhaps the most readable. Either should be fine for MISRA.
As for why stdbool.h defines true/false to be 1/0, it is because the standard explicitly says so. Boolean conditions in C still use int type, and not bool type like in C++, for backwards compatibility reasons.
It is however considered good style to treat boolean conditions as if C had a true boolean type. MISRA-C:2012 has a whole set of rules regarding this concept, called essentially boolean type. This can give better type safety during static analysis and also prevent various bugs.
It's for using smallish integer literals where the context won't result in the compiler casting it to the correct size.
I've worked on an embedded platform where int is 16 bits and long is 32 bits. If you were trying to write portable code to work on platforms with either 16-bit or 32-bit int types, and wanted to pass a 32-bit "unsigned integer literal" to a variadic function, you'd need the cast:
#define BAUDRATE UINT32_C(38400)
printf("Set baudrate to %" PRIu32 "\n", BAUDRATE);
On the 16-bit platform, the cast creates 38400UL and on the 32-bit platform just 38400U. Those will match the PRIu32 macro of either "lu" or "u".
I think that most compilers would generate identical code for (uint32_t) X as for UINT32_C(X) when X is an integer literal, but that might not have been the case with early compilers.

C: enum with string values [duplicate]

Why is this a warning? I think there are many cases when is more clear to use multi-char int constants instead of "no meaning" numbers or instead of defining const variables with same value. When parsing wave/tiff/other file types is more clear to compare the read values with some 'EVAW', 'data', etc instead of their corresponding values.
Sample code:
int waveHeader = 'EVAW';
Why does this give a warning?
According to the standard (§6.4.4.4/10)
The value of an integer character constant containing more than one
character (e.g., 'ab'), [...] is implementation-defined.
long x = '\xde\xad\xbe\xef'; // yes, single quotes
This is valid ISO 9899:2011 C. It compiles without warning under gcc with -Wall, and a “multi-character character constant” warning with -pedantic.
From Wikipedia:
Multi-character constants (e.g. 'xy') are valid, although rarely
useful — they let one store several characters in an integer (e.g. 4
ASCII characters can fit in a 32-bit integer, 8 in a 64-bit one).
Since the order in which the characters are packed into one int is not
specified, portable use of multi-character constants is difficult.
For portability sake, don't use multi-character constants with integral types.
This warning is useful for programmers that would mistakenly write 'test' where they should have written "test".
This happen much more often than programmers that do actually want multi-char int constants.
If you're happy you know what you're doing and can accept the portability problems, on GCC for example you can disable the warning on the command line:
-Wno-multichar
I use this for my own apps to work with AVI and MP4 file headers for similar reasons to you.
Even if you're willing to look up what behavior your implementation defines, multi-character constants will still vary with endianness.
Better to use a (POD) struct { char[4] }; ... and then use a UDL like "WAVE"_4cc to easily construct instances of that class
Simplest C/C++ any compiler/standard compliant solution, was mentioned by #leftaroundabout in comments above:
int x = *(int*)"abcd";
Or a bit more specific:
int x = *(int32_t*)"abcd";
One more solution, also compliant with C/C++ compiler/standard since C99 (except clang++, which has a known bug):
int x = ((union {char s[5]; int number;}){"abcd"}).number;
/* just a demo check: */
printf("x=%d stored %s byte first\n", x, x==0x61626364 ? "MSB":"LSB");
Here anonymous union is used to give a nice symbol-name to the desired numeric result, "abcd" string is used to initialize the lvalue of compound literal (C99).
If you want to disable this warning it is important to know that there are two related warning parameters in GCC and Clang: GCC Compiler options -wno-four-char-constants and -wno-multichar

Why does scanf("%i",a) not take binary like 0b101?

I'm confused about the binary expression like 0b10101:
#include <stdio.h>
int main(void) {
int a,b;
b = 0b101;
scanf("%i",&a);
printf("the value of a is %d\n", a);
printf("the value of b is %d\n", b);
}
when I type 0b101,
the output gives me
the value of a is 0;
the value of b is 5;
instead of two 5's as it should be.
Is there any way to make scanf take binary input?
Standard C has no specific notation prefix for representing binary notation. Only decimal, octal and hexadecimal are supported. Although the 0b prefix was proposed for C99 (and rejected), so it is probably not unusual to see it implemented in some compilers.
Even if you saw 0b prefix supported by some specific C implementation as an extension (GCC?), it would be rather surprising see it recognized by scanf's %i format specifier, since it would break compatibility with standard implementations. The latter are required to stop reading at b.
Judging by your test results though it appears that the compiler supports 0b... integral literals, while the standard library knows nothing about them. Maybe the documentation for that library has something to say about it, like some extended non-standard format specifier/flag for scanf that makes it recognize 0b... prefixes. I don't see it in GCC docs though.

printf with sizeof on 32 vs 64 platforms: how do I handle format code in platform independent manner?

I have some code that prints the amount of memory used by the program. The line is similar to this:
printf("The about of RAM used is %u", anIntVariable*sizeof(double) );
where anIntVariable is an int variable for the number of elements of the double array. Anyhow, on 32-bit systems I never had any problems but on 64-bit systems, I get a compiler warning about using "%u" for a unsigned long integer. Using "%lu" as the format code fixes the problem on 64-bit but causes the compiler to complain on 32-bit because the type is back to unsigned int. I've found that, indeed, sizeof(double) returns a different value on 32 vs 64 bit systems. I've found some webpage guides to convert code from 32 bit to 64 bit But I'd rather have code that works on both instead of just converting back and forth.
How do I write this line in a platform independent way? I know many ways I could do it using preprocessor directives but that seems like a hack. Surely there's an elegant way that I'm not realizing.
Portable printf identifiers are provided in the include file inttypes.h or here.
This include file has many portable identifiers for your specific runtime. For your example, you want PRIuPTR, which means "PRintf Identifier unsigned with size of up to a pointer's size".
Your example will then be:
printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );
Results on 64bit Linux with GCC 4.3 (int anIntVariable = 1):
$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8
For completeness sake, there are identifiers for scanf too, whose prefixes are SCN.
The return value of sizeof is a size_t. If you're using a C99 compliant compiler it looks like you can use %zd%zu for this.
D'oh: %zu (unsigned) of course. Thanks, ony.
First of all, you should match the "%" specifier with the actual data type you want to print. sizeof returns the data type size_t, and just as you shouldn't try to print a float using a "%d" specifier, you shouldn't try to print a size_t with "%u" or "%d" or anything that doesn't really mean size_t.
The other replies have given some good ways to handle this with newer compilers ("%z" and PRIu32), but the way we used to do this was simply to cast the size_t to unsigned long, and then print it using "%lu":
printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );
This will not work on systems where size_t is wider than a long, but I don't know of any such systems, and I'm not even sure if the standard allows it.

Resources