Assign statement and overflow check - c

I got one question when looking into KVM-QEMU source codes.
ram_size = sz;
if (ram_size != sz) {
fprintf(stderr, "qemu: ram size too large\n");
exit(1);
}
sz is uint64_t and ram_size is ram_addr_t, which is also defined as uint64_t.
What are the above codes used for (check integer overflow)? How does it work?
Thanks.

If you look closer at the definition of ram_addr_t, you'll see something like:
/* address in the RAM (different from a physical address) */
#if defined(CONFIG_XEN_BACKEND)
typedef uint64_t ram_addr_t;
# define RAM_ADDR_MAX UINT64_MAX
# define RAM_ADDR_FMT "%" PRIx64
#else
typedef uintptr_t ram_addr_t;
# define RAM_ADDR_MAX UINTPTR_MAX
# define RAM_ADDR_FMT "%" PRIxPTR
#endif
Note that it might also be a uintptr_t, which might not be a 64-bit type. In that case, there'd be a problem with that assignment if sz were greater than UINTPTR_MAX.

Related

Hide single item on a struct

I need to hide a single field, not several, inside a structure:
struct MyType1
{
unsigned char Value;
}; //
struct MyType2
{
unsigned void* Value;
} ; //
struct MyType3
{
signed int;
} ; //
What I want is to have the struct type to have the same size, if possible, that the primitive type variables, but that the compiler treated it like a new type.
In some part of the code I want to cast back the structures,
to the simple value.
And also create arrays with this struct type but,
with little space.
MyType1 MyArray[255];
I already check previous answers, but, didn't find it.
Example:
typedef
unsigned int /* rename as */ mydatetime;
// Define new type as
struct mydatetimetype
{
unsigned int /* field */ value;
} ;
Let's suppose I have these functions in the the same program, but different include files :
void SomeFunc ( unsigned int /* param */ anyparam );
void SomeFunc ( mydatetime /* param */ anyparam );
void SomeFunc ( mydatetimetype /* param */ anyparam );
My programming editor or I.D.E. confuses the first two functions.
In some part of the code, later, I will use the packed type with integer operations, but I should be hidden from other programmers, that use this type.
Note that, I also want to apply this feature to other types like pointers or characters.
And, "forwarding" or using an "opaque" structure is not necessary.
How does a single field structure gets padded or packed ?
Should I add an attribute to pack or pad this structure for better performance ?
Is there already a name for this trick ?
I hope that the code below may help you.
The code show you how you may use union to obtain that more type uses the same memory space.
The result of this code might be implemantation dependent, anyway it demonstraits you that all the types specified into the integers union share the same memory space.
A variable declared as integers (in the code is k) is always long as the longer type into the declaration. Then we have that, in the code, the variable k may contains integer types from 8 bits to 64 bits using always 64 bits.
Although I only used integer types, the type you may use inside union declarations may be of whatever type you want also struct types and/or pointers.
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
typedef union integers {
int8_t i8;
int16_t i16;
int32_t i32;
int64_t i64;
} integers;
typedef struct sInt {
integers a;
integers b;
} sInt;
int main(void) {
integers k;
sInt s;
k.i64=0x1011121314151617;
printf("Int 08: %" PRIx8 "h\n", k.i8 );
printf("Int 16: %" PRIx16 "h\n", k.i16 );
printf("Int 32: %" PRIx32 "h\n", k.i32 );
printf("Int 64: %" PRIx64 "h\n", k.i64 );
s.a.i64=0x1011121314151617;
s.b.i64=0x0102030405060708;
printf("Int a.08: %" PRIx8 "h\n", s.a.i8 );
printf("Int a.16: %" PRIx16 "h\n", s.a.i16 );
printf("Int a.32: %" PRIx32 "h\n", s.a.i32 );
printf("Int a.64: %" PRIx64 "h\n", s.a.i64 );
printf("Int b.08: %" PRIx8 "h\n", s.b.i8 );
printf("Int b.16: %" PRIx16 "h\n", s.b.i16 );
printf("Int b.32: %" PRIx32 "h\n", s.b.i32 );
printf("Int b.64: %" PRIx64 "h\n", s.b.i64 );
return 0;
}
Note: If your problem is the padding into the structure this code is not entirely the answer you're searching for. To manage padding you have to use #pragma pack() (gcc and other compilers manage #pragmas)
Structs can be padded to align address boundaries. So your first and third struct more likely will not have the same size as primitive types.
Single-field structs more likely be padded "behind" the field, but C standard does not state how compiler should carry this out.
You should add attribute if you want cast your structure to primitive type (to be sure you are casting value it stores and not garbage in padding) but, i think (and do not recommend) possible to cast structure to variable and get correct result even without attributes (though it is very implementation dependent). But you will get small performance penalty for every processor attempt to load non-aligned structure from memory.
Also you should be careful, because packing structs may be dangerous

What happens if arguments passed to sscanf are cast

While reviewing and old piece of code, I stumbled upon some coding horror like this one:
struct Foo
{
unsigned int bar;
unsigned char qux;
unsigned char xyz;
unsigned int etc;
};
void horror(const char* s1, const char* s2, const char* s3, const char* s4, Foo* foo)
{
sscanf(s1, "%u", &(foo->bar));
sscanf(s2, "%u", (unsigned int*) &(foo->qux));
sscanf(s3, "%u", (unsigned int*) &(foo->xyz));
sscanf(s4, "%u", &(foo->etc));
}
So, what is actually happening in the second and third sscanf, with the argument passed being a unsigned char* cast to unsigned int*, but with the format specifier for an unsigned integer? Whatever happens is due to undefined behavior, but why is this even "working"?
As far as I know, the cast effectively does nothing in this case (the actual type of the arguments passed as ... is unknown to the called function). However this has been in production for years and it has never crashed and the surrounding values apparently are not overwritten, I suppose because the members of the structure are all aligned to 32 bits. This is even reading the correct value on the target machine (a little endian 32 bit ARM) but I think that it would no longer work on a different endianness.
Bonus question: what is the cleanest correct way to do this? I know that now we have the %hhu format specifier (apparently introduced by C++11), but what about a legacy C89 compiler?
Please note that the original question had uint32_t instead of unsigned int and unsigned char instead of uint8_t but that was just misleading and out of topic, and by the way the original code I was reviewing uses its own typedefs.
Bonus question: what is the cleanest correct way to do this? I know that now we have the %hhu format specifier (apparently introduced by C++11), but what about a legacy C89 compiler?
The <stdint.h> header and its types were introduced in C99, so a C89 compiler won't support them except as an extension.
The correct way to use the *scanf() and *printf() families of functions with the various fixed or minimum-width types is to use the macros from <inttypes.h>. For example:
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int8_t foo;
uint_least16_t bar;
puts("Enter two numbers");
if (scanf("%" SCNd8 " %" SCNuLEAST16, &foo, &bar) != 2) {
fputs("Input failed!\n", stderr);
return EXIT_FAILURE;
}
printf("You entered %" PRId8 " and %" PRIuLEAST16 "\n", foo, bar);
}
In this case from the pointer point of view nothing as on the all modern machines pointers are the same for all types.
But because you use wrong formats - the scanf will write outside the memory allocated to the variables and it is an Undefined Behaviour.
First of all, this of course invokes Undefined Behaviour.
But that kind of horror was quite common in old code, where the C language was used as a higher level assembly language. So here are 2 possible behaviours:
the structure has a 32 bits alignment. All is (rather fine) on a little endian machine: the uint8_t members will recieve the least significant byte of the 32 bits value and the padding bytes will be zeroed (I assume that the program does not try to store a value greater than 255 into an uint8_t)
the structure has not a 32 bits alignement, but the architecture allows scanf to write into mis-aligned variables. The least significant byte of the value read for qux will correctly go into qux and the next 3 zero bytes will erase xyz and etc. On next line, xyz receives its value and etc recieves one more 0 byte. And finally etc will recieve its value. This could have been a rather common hack in the early 80' on an 8086 type machine.
For a portable way, I would use an temporary unsigned integer:
uint32_t u;
sscanf(s1, "%u", &(foo->bar));
sscanf(s2, "%u", &u);
foo->qux = (uint8_t) u;
sscanf(s3, "%u", &u);
foo->xyz = (uint8_t) u;
sscanf(s4, "%u", &(foo->etc));
and trust the compiler to generate code as efficient as the horror way.
OP code is UB as scan specifiers does not match arguments.
cleanest correct way to do this?
Cleaner
#include <inttypes.h>
void horror1(const char* s1, const char* s2, const char* s3, const char* s4, Foo* foo) {
sscanf(s1, "%" SCNu32, &(foo->bar));
sscanf(s2, "%" SCNu8, &(foo->qux));
sscanf(s2, "%" SCNu8, &(foo->xyz));
sscanf(s1, "%" SCNu32, &(foo->etc));
}
Cleanest
Add additional error handling if desired.
void horror2(const char* s1, const char* s2, const char* s3, const char* s4, Foo* foo) {
foo->bar = (uint32_t) strtoul(s1, 0, 10);
foo->qux = (uint8_t) strtoul(s1, 0, 10);
foo->xyz = (uint8_t) strtoul(s1, 0, 10);
foo->etc = (uint32_t) strtoul(s1, 0, 10);
}

C variable type assert

uint32_t fail_count = 0;
...
if(is_failed)
if(fail_count < UINT32_MAX - 1 )
++fail_count;
It works fine, but this code is fragile. Tomorrow, I may change the type of fail_count from uint32_t to int32_t and I forget to update UINT32_MAX.
Is there any way to assert fail_count is a uint32_t at the function where I have written my ifs?
P.S. 1- I know it is easy in C++ but I'm looking for a C way.
P.S. 2- I prefer to use two asserts than relying on the compiler warnings. Checking the number size via sizeof should work but is there any way to distinguish if type is unsigned?
As of C11, you can use a generic selection macro to produce a result based on the type of an expression. You can use the result in a static assertion:
#define IS_UINT32(N) _Generic((N), \
uint32_t: 1, \
default: 0 \
)
int main(void) {
uint32_t fail_count = 0;
_Static_assert(IS_UINT32(fail_count), "wrong type for fail_count");
}
You could of course use the result in a regular assert(), but _Static_assert will fail at compile time.
A better approach could be dispatching the comparison based on type, again using generic selection:
#include <limits.h>
#include <stdint.h>
#define UNDER_LIMIT(N) ((N) < _Generic((N), \
int32_t: INT32_MAX, \
uint32_t: UINT32_MAX \
) -1)
int main(void) {
int32_t fail_count = 0;
if (UNDER_LIMIT(fail_count)) {
++fail_count;
}
}
As you mentioned GCC, you can use a compiler extension to accomplish this in case you are not using C11:
First write a macro that emulates the C++ is_same. And then call it with the types you want to compare.
A minimal example for your particular case:
#include<assert.h>
#define is_same(a, b) \
static_assert(__builtin_types_compatible_p(typeof(a), typeof(b)), #a " is not unsigned int")
int main()
{
int fail_count = 0;
is_same(fail_count, unsigned int);
}
The compiler asserts:
<source>: In function 'main':
<source>:4:3: error: static assertion failed: "fail_count is not unsigned int"
static_assert(__builtin_types_compatible_p(typeof(a), typeof(b)), #a " is not unsigned int")
^~~~~~~~~~~~~
<source>:9:5: note: in expansion of macro 'is_same'
is_same(fail_count, unsigned int);
^~~~~~~
See Demo
What about a low-tech solution that works even with K&R C and any compiler past and present?
Place the right comment in the right place:
/*
* If this type is changed, don't forget to change the macro in
* if (fail_count < UINT32_MAX - 1) below (or file foobar.c)
*/
uint32_t fail_count = 0;
With a proper encapsulation this should refer to exactly one place in the code.
Don't tell me you increment the fail count in many places. And if you do, what
about a
#define FAIL_COUNT_MAX UINT32_MAX
right next to the declaration? That's more proper and clean code anyway.
No need for all the assertion magic and rocket sciencery :-)

How to determine pointer size preprocessor C

I am working on a software implementation of OpenGL, and OpenGL seems to require that I return 32-bit pointers. To save time, I am putting this into a C equivalent of map with 64-bit systems in order to retrieve 64-bit pointers from 32-bit psuedo-addresses. However, on 32-bit systems, this would cause a hassle, and so I should just use the pointer verbatim.
Here is basically what I want to do in my shared header:
#if <64-bit>
#include <search.h>
extern void * pointerTable;
typedef struct {
int key;
void* value;
} intPtrMap;
inline int compar(const void *l, const void *r) {
const intPtrMap *lm = l;
const intPtrMap *lr = r;
return lm->key - lr->key;
}
inline uint32_t allocate(size) {
void* result = malloc(size);
intPtrMap *a = malloc(sizeof(intStrMap));
a->key = (uint32_t) result;
a->value = result;
tsearch(a, &pointerTable, compar);
return (uint32_t) result;
}
inline int getPtr(ptr) {
intPtrMap *find_a = malloc(sizeof(intPtrMap));
find_a->key = ptr;
void *r = tfind(find_a, &root, compar);
return (*(intPtrMap**)r)->value;
}
#else
inline uint32_t allocate(size) {
return (uint32_t) malloc(size);
}
inline uint32_t getPtr(ptr) {
return (uint32_t) ptr;
}
#endif
Any suggestions on how to do the first if?
How to determine pointer size preprocessor C (?)
To determine pointer size in a portable fashion is tricky.
Various pointers sizes
It is not uncommon to have a pointer to a function wider than a pointer to an object or void*.
Pointers to int char, struct can be of different sizes, although that is rare.
So let us reduce the task to determine void * pointer size.
Pre-processor math
PP math is limited, so code needs to be careful. Let us stay with integer math.
(u)intptr_t
The optional types (u)intptr_t, which are very commonly available, are useful here. They allow conversion of a void * to an integer and then to an equivalent void*.
Although the integer type size may differ from the pointer type, that, I assert is rare and detectable with _Static_assert from C11.
Following will handle many C11 platforms. Useful ideas toward a general solution.
#include <stdint.h>
// C11
_Static_assert(sizeof (void*) == sizeof (uintptr_t),
"TBD code needed to determine pointer size");
// C99 or later
#if UINTPTR_MAX == 0xFFFF
#define PTR16
#elif UINTPTR_MAX == 0xFFFFFFFF
#define PTR32
#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu
#define PTR64
#else
#error TBD pointer size
#endif
[Edit 2021]
With Is there any way to compute the width of an integer type at compile-time?, code could use, at compile time, the below to find the width of uintptr_t.
/* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))
#define UINTPTR_MAX_BITWIDTH IMAX_BITS(UINTPTR_MAX)
Using other questions on StackOverflow and also a solution from somebody on Discord, I have cobbled together this solution:
#if _WIN32 || _WIN64
#if _WIN64
#define PTR64
#else
#define PTR32
#endif
#elif __GNUC__
#if __x86_64__ || __ppc64__
#define PTR64
#else
#define PTR32
#endif
#elif UINTPTR_MAX > UINT_MAX
#define PTR64
#else
#define PTR32
#endif
This should be able to reliably determine 64-bit or 32-bit pointer usage in preprocessor.

Passing a type as a parameter

ETA: This is NOT about malloc(), or memory allocation, it's about passing a type as a parameter, like:
va_arg(l, char);
I'm using malloc() as a simple example.
This might be a stupid question, or perhaps I'm missing something.
Let's imagine I want to write a simple function that allocates some memory, not any particular type of memory but something more flexible.
Like, say I wanted 1,000 chars allocated and returned. So I'd like a function that I can call like this:
ptr = getMem(char, 1000);
Pasing the actual type as a parameter, which could be useful.
Now I know macros like va_arg() can do this:
fprintf(stdout, "%s\n", va_arg(l, char));
So I looked into it a bit, it's all rather vague. I found this:
type va_arg(va_list ap, type)
Parameters
ap − This is the object of type va_list with information about the additional arguments and their retrieval state. This object should be initialized by an initial call to va_start before the first call to va_arg.
type − This is a type name. This type name is used as the type of the expression, this macro expands to.
You can see cleary the type for the first parameter is defined as va_list,
but the second parameter, the one I'm interested in - is simply specified as type.
So it started to bug me, I've been messing around with bum code like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void *getMem(type, int size) {
return malloc(sizeof(type) * size);
}
int main(void)
{
void *mem;
mem = getMem(1000, char);
if (mem == NULL) {
perror("malloc()");
exit(EXIT_FAILURE);
}
fprintf(stdout, "Memory allocated successfully!\n");
free(mem);
exit(EXIT_SUCCESS);
}
I've been sniffing around include files trying to figure this out but to no avail, is there a way I can do this?
Sorry if it's a bit vague or nonsensical, but if va_arg() can do it I reckon I should be able to, also.
Much obliged.
Do this with a CPP macro:
#define getMem(type, size) \
malloc(sizeof(type) * size)
However, personally, I prefer this:
#define getMemOf(ptr, size) \
ptr = malloc(sizeof(*ptr) * size)
// invoke with:
getMemOf(ptr, 1000);
_Generic in C99 C11 may offer something close to OP's need.
Example: Code wants to assign the maximum value of a common integer type.
#define integer_max(X) _Generic((X), \
unsigned long long: ULLONG_MAX, \
long long: LLONG_MAX, \
unsigned long: ULONG_MAX, \
long: LONG_MAX, \
unsigned: UINT_MAX, \
int: INT_MAX, \
unsigned short: USHRT_MAX, \
short: SHRT_MAX, \
unsigned char: UCHAR_MAX, \
signed char: SCHAR_MAX, \
char: CHAR_MAX, \
_Bool: 1, \
default: 1/0 \
)
// Here the _type_ of `x` is used by integer_max(), not its value.
some_integer_type x = integer_max(x);
You are going to end up doing this with sizeof anyway. I just checked this in Visual Studio, and Microsoft defines it as (across several defines)
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_arg _crt_va_arg
You can find these in vadefs.h. Long story short, you're not going to get away from using sizeof somewhere, so you should just do it where it is most simple. Personally I think that'd be just passing the size into your getMem function instead of the type will save you way more headache in the long run.
malloc() does not need to know the type to work well, just the size of the type.
Should code want to insure no overflow in the size calculation, a check could be made.
void *getMem(size_t element_count, size_t type_size) {
if (element_count > SIZE_MAX/type_size) return NULL;
return malloc(element_count * size);
}
// usage example
size_t element_count,
void * p = getMem(element_count, sizeof (char));
If one wants zero-ed memory, simple use calloc()
// usage example
size_t element_count,
void * p = calloc(element_count, sizeof (char));
Recommend that code not use void * pointers and expresses a type like char separately. Instead, declare a pointer with a non-void type.
#define ALLOCATE_ASSIGN(addr_ptr, count) (*(addr_ptr)=malloc(sizeof **(addr_ptr) * count))
some_type *mem;
ALLOCATE_ASSIGN(&mem, element_count);

Resources