How do I ensure each and every field of my structures are initialized in GCC when using designated initializers? (I'm especially interested in function pointers.) (I'm using C not C++.)
Here is an example:
typedef struct {
int a;
int b;
} foo_t;
typedef struct {
void (*Start)(void);
void (*Stop)(void);
} bar_t;
foo_t fooo = {
5
};
foo_t food = {
.b=4
};
bar_t baro = {
NULL
};
bar_t bard = {
.Start = NULL
};
-Wmissing-field-initializers does not help at all. It works for fooo only in GCC (mingw 4.7.3, 4.8.1), and clang does only marginally better (no warnings for food and bard).
I'm sure there is a reason for not producing warnings for designated initializer (even when I explicitly ask for them) but I want/need them. I do not want to initialize structures based on order/position because that is more error prone (for example swapping Start and Stop won't even give any warning). And neither gcc nor clang will give any warning that I failed to explicitly initialize a field (when initializing by name). I also don't want to litter my code with if(x.y==NULL) lines for multiple reasons, one of which is I want compile time warnings and not runtime errors.
At least splint will give me warnings on all 4 cases, but unfortunately I cannot use splint all the time (it chokes on some of the code (fails to parse some C99, GCC extensions)).
Note: If I'm using a real function instead of NULL GCC will also show a warning for baro (but not bard).
I searched google and stack overflow but only found related questions and have not found answer for this specific problem.
The best match I have found is 'Ensure that all elements in a structure are initialized'
Ensure that all elements in a structure are initialized
Which asks pretty much the same question, but has no satisfying answer.
Is there a better way dealing with this that I have not mentioned?
(Maybe other code analysis tool? Preferably something (free) that can be integrated into Eclipse or Visual Studio...)
If I'm not mistaken, the C standards specify that the other fields are automatically initialized with 0.
So what you are asking for - a compilation error when fields are not initialized - would be out of line with the C (modern?) specifications.
C99 standard, page 127 in: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.
gccs -Wmissing-field-initializers is documented to not warn with designated initializers. There is a request for an enhancement -Wmissing-field-initializers=2 that would then warn also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39589
So I suggest you add your wish to that bug report, or maybe even provide a patch. From my experience with open-source software, adding a patch is best.
The four ways you have showed all initialize the rest of the structure. It's initialized to 0 (or the type equivalent).
Related
NOTE: This is NOT a duplicate of the question linked by Paul T, because I am asking if it is possible to determine if a type is of a certain broader incomplete type/kind at compile time, not if a symbol has been registered at compile time. This seems like a fundamental misunderstanding of the question.
I am writing a library in C that deals with pseudo-generic functions which take a type as an argument through a macro wrapper.
To spare the details (because they are rather complicated) there are two possible features that could help, I think:
Being able to detect if a type is a pointer at compile time. (No, the "use _Generic to test if you get ptrdiff_t from subtraction" trick won't work, because structures are a possibility, and you can't subtract structures.)
Being able to detect if a type is a struct at compile time. (If this was possible, then the aforementioned _Generic trick could be used if the type was detected as not being a struct.)
I've tried everything I could think of on Godbolt (even trying to compare types to incomplete anonymous structs and toying with __builtin_types_compatible_p) and wasn't able to find any solutions.
If anyone has any solutions I'd love to see them, otherwise I may just end up having to complicate the design a bit-- so not the end of the world if it's impossible, but it would be ideal if it can be done.
To give a basic idea of what one of these macros might look like or their expected output:
int *a;
assert(!IS_STRUCT(a));
assert(IS_POINTER(a));
struct {} b;
assert(IS_STRUCT(b));
assert(!IS_POINTER(b));
shouldn't throw any errors.
Complete Answer (if EDG Front End used):
If your IDE / compiler is using the EDG C++ Front End (which a lot are), and you are using C, not C++ (which your tag suggests), and you say you ARE using typeof, then you can detect a structs as follows (see the latest manual, page 75):
/* Test if EDG Front End is used*/
#if defined(__EDG__) && defined(__EDG_VERSION__)
#define IS_STRUCT(expression_or_type_name) __is_class(typeof (expression_or_type_name)))
#endif
since in C __is_class() will only be true for a struct (http://www.cplusplus.com/reference/type_traits/is_class/).
Further, pointers can similarly be detected as follows:
/* Test if EDG Front End is used*/
#if defined(__EDG__) && defined(__EDG_VERSION__)
#define IS_POINTER(expression_or_type_name) (__is_convertible_to(typeof (expression_or_type_name), void*) || __is_convertible_to(typeof (expression_or_type_name), void const*) || __is_convertible_to(typeof (expression_or_type_name), void volatile*) || __is_convertible_to(typeof (expression_or_type_name), void const volatile*))
#endif
(http://www.cplusplus.com/reference/type_traits/is_convertible/)
Itβs not possible in standard C. Whatever solutions there may be must be implementation-defined.
It seems that C is not a suitable language for your problem domain. Short of esoteric platforms that come without C++ support, there seems to be little reason to have to solve this in C. On most any platform where C is available, so is C++. Since you claim that you use gcc, then C++ is surely available and you can process some of the input using a C++ compiler. You could do the input processing as a generator step: run the code through a C++ compiler to generate source code that defines constants that capture type properties sought.
There is simple code, where clang and gcc behave differently.
int t;
extern void abort (void);
int f(int t, const int *a)
{
const int b[] = { 1, 2, 3};
if (!t)
return f(1, b);
return b == a;
}
int main(void)
{
if (f(0, 0))
abort ();
return 0;
}
Clang:
> clang -v
clang version 4.0.1 (tags/RELEASE_401/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
> clang test.c
> ./a.out
Aborted
GCC:
> gcc -v
Target: x86_64-suse-linux
Thread model: posix
gcc version 7.2.0 (GCC)
> gcc test.c
> ./a.out
> echo $?
0
Reason is pretty obvious: behavior is implementation defined and clang merges constant local arrays to global one.
But lets say I want consistent behavior. Can I turn some switch on or off in clang to disable this optimization and make it honestly create different local arrays (even constant ones) for different stack frames?
The option in clang you're looking for is -fno-merge-all-constants. And you can enable it in gcc with -fmerge-all-constants if you want to achieve the opposite. But the documentation of the option in gcc makes me curious:
Languages like C or C++ require each variable, including multiple instances of the same variable in recursive calls, to have distinct locations, so using this option results in non-conforming behavior.
The only bit that somehow might suggest that clang is allowed to get away with this is (C11, 6.5.2.4):
String literals, and compound literals with const-qualified types, need not designate distinct objects.
The problem here is that your code doesn't have a compound literal.
There is in fact a bug report for clang about this and it appears that the developers are aware that this is non-conforming: https://bugs.llvm.org/show_bug.cgi?id=18538
The interesting comment in there is:
This is the only case I can think of (off the top of my head) where clang deliberately does not conform to the standard by default, and has a flag to make it conform. There are a few other places where we deliberately don't conform because we think the standard is wrong (and generally we try to get the standard fixed in those cases).
It does appear that clang is reusing the same array for variable b in both local scopes of f(), but that cannot be justified on the basis of implementation-defined behavior. Implementation-defined behaviors are explicitly called out in the standard, and conforming implementations document their actual behavior for each area of implementation-defined behavior. This is not an area where the standard grants such latitude.
On the contrary, the behavior of the clang-generated program is non-conforming, and Clang is non-conforming for producing such code. The standard specifically says that
For [an object with automatic storage duration] that does not have a variable length array type,
its lifetime extends from entry into the block with which it is
associated until execution of that block ends in any way. (Entering an
enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively,
a new instance of the object is created each time.
(C2011, 6.2.4/6; emphasis added)
The objects in question in this case do have automatic storage duration and do not have variable-length array type, so the standard specifies that they be distinct objects. That they are arrays with a const-qualifed element type does not permit clang to reuse the array.
But lets say I want consistent behavior. Can I turn some switch on or off in clang to disable this optimization and make it honestly create different local arrays (even constant ones) for different stack frames?
You can and should reported a bug against Clang, unless this issue has already been reported. The time frame for that bug being fixed is probably longer than you want to wait, but I do not find documentation of any command-line flag that would modulate this behavior.
The other answer suggests that there is in fact an option controlling this behavior. I'm entirely prepared to believe that, as I have previously found Clang's documentation to be incomplete in other ways, but it should not be necessary to explicitly turn off such an option to achieve language conformance.
Before someone instantly marks this as a duplicate, let me say that I have spent a few hours searching for an answer to this (and read many similar S/O questions)
Here's the situation: I'm playing around with _Generic and trying to implement a dictionary structure which auto-casts upon retrieval. Let me explain (if you don't care, skip ahead to the bold header). From what I see, the go-to way to have a dictionary structure in which all values belong to the same field involves void pointers, which require the user to cast upon retrieval; here is an example:
struct C99_Dict *d = new_C99_Dict(); /* Creates a pointer to an empty dict
d: {} */
int i = 7;
put_in_c99_dict(d,"key",i); /* d: {"key": (void *)&i} */
...
// BAD: Will cast to i's address
int j = get_from_c99_dict(d,"key");
// BAD: Dereferencing void pointer
int k = *(get_from_c99_dict(d,"key"));
// GOOD: Will set l equal to 7
int l = *(int *)get_from_c99_dict(d,"key");
As one might imagine, after a while (especially once struct *s get thrown into the mix...although that's unchanged in my current project) your code ends up looking like something out of a Lisp textbook.
Using _Generic, however, I have managed to figure out a way to make an easier-to-use dictionary which auto-casts in such a fashion that the line
int j = get_from_c11_dict(d,"key");
becomes perfectly valid and works as one would expect (for builtins...structs still require manual casting). Changing the behavior of put_in_c11_dict based on the input type is easy enough, for the _Generic keyword does all of the heavy lifting. What is difficuly, however, is the notion of casting on the way out. This is because, in order for the dictionary struct to be well-defined, its value must be a consistent type (e.g. void*, as I have implemented). The problem with this, however, is that the type information is lost after the insertion function has processed the given input.
My initial (failed) attempt at a workaround for this was to make a dictionary struct of the following form:
typedef struct _dict_mem_struct{
union {
_Bool(*bool_get)(_dict_mem_struct*);
char(*char_get)(_dict_mem_struct*);
...
char *(*char_point_get)(_dict_mem_struct*);
void *(*void_point_get)(_dict_mem_struct*);
} get;
void *value;
} _dict_mem_t;
In hopes of (albeit perhaps foolishly so) being able to do the following in a _get helper macro definition:
#define _get(mem_struct) _Generic((mem_struct.get) ... )
Unfortunately, I then learned from gdb that mem_struct.get was of type union, so it was back to the drawing board. Eventually, I got something that worked. First, I added a char* field to the member structure which contained the original type. Then what I really needed was an inlined switch statement, since I had no prior indication of what the function signature would be. So, here's the hideous thing I did (is it technically invalid C? Maybe. Probably. I don't know. Nevertheless, GCC compiles it and it works, so I'm happy.)
#define IS_PFX(val,pfx) (!strcmp(val->pfx, pfx))
#define _get(valstruct) (IS_PFX(valstruct,"bool") ? boolval(valstruct) : IS_PFX(valstruct,"char") ? charval(valstruct) : ... : valstruct)
Yeah, I know; I'm probably going to hell for this. So, with that...
Here's my actual problem: When I compile this, it works, but gcc gets extremely upset with me. It gives me a bunch of errors such as
dict.c:203:75: warning: pointer type mismatch in conditional expression
#define PAIR(valstruct,str,fn,rst) (IS_PFX(valstruct,str) ? fn(valstruct) : rst)
From what I can gather, this means gcc is upset that these functions are all of different types. Nevertheless, as previously stated, the code works, so I would like to tell gcc to put a sock in it for specifically those warnings. The problem is that when I run gcc -fdiagnostics-show-option, those warning lines have no -W... flag after them. Furthermore, I have read through the gcc warning flag page, and nothing stands out as obvious to me which I could use to suppress these. Finally, the warnings still do not go away after adding the lines #pragma GCC diagnostic ignored "-Wall" and #pragma GCC diagnostic ignored "-Wextra". How can I get rid of these? Another solution I would be fine with is somehow turning off all warnings for specifically that file, since the reason I don't want them is so that I can integrate this into other projects without headache.
Thanks for any and all assistance. By the way, if there is some better way to do all of this, then please let me know. Regardless, I'm thinking I'll make a git repo for this once I've worked some of these kinks out, since I think it would be useful (if so, I'll update this post with a link).
gcc is probably right, you are mixing different pointer types in a ternary expression. So your design is most probably wrong. Have in mind that _Generic can't do miracles, the type system in C remains static, determined at compile time. It can only take care of type information that you pass to it in the first expression.
If you cast away type information to void*, store the pointer somewhere and try to retrieve it later, by definition _Generic can't help you. The context of the retrieval doesn't have the type information anymore, it might be called for such pointers that come from different places.
So in particular for a dictionary structure C can never know at the retrieval side, what type the original pointer had been. If you want to keep that information, you'd have to do that yourself and store that information along with the pointer.
BTW, already your question title is wrong: there is no such thing as a generic function in C. There are type generic function-like macros.
In a discussion, a colleague told me that he never uses enum because he experienced that some C-compilers don't cope with the enum statement correctly.
He couldn't remember which compiler exactly had problems but among the problems, there were errors when doing something like
enum my_enum{
my_enum_first = 5;
my_enum_second = 10;
};
i.e. initializing enum values instead of letting the compiler do the automatic assignment. Another one was that the compiler decides for itself how big the enum is and therefore you could have unpredictable behavior for sizeof my_enum when compiling your code under various platforms.
To get around that, he told me to better use #defines to define the constant elements. But especially for using doxygen it's quite handy to have an enum (e.g. as function parameter) because in the generated documentation, you could simply click on my_enum and directly jump to the description of my_enum.
Another example would be code completion, where your IDE tells you what you could specify as valid parameters for functions. I know that β as long as you're compiling the code as C-code β that there's no type-safety (i.e. I could also specify 5 instead of my_enum_first), so the use of an enum seems to be a more cosmetic thing.
The question is: do you know any compilers that have limitations regarding the usage of enum?
Edit 1:
Regarding the environment: we are developing for various embedded platforms, so there could also be a compiler for some obscure micro-controller...
Edit 2:
He could tell me that the KEIL C51 compiler didn't play well with enums. Are there any experiences with current versions of the C51 compiler?
Compilers are free to choose the size of an enum based on its range of possible values. This only really becomes an issue if you're exposing enums in your API, and users of your code may be using a different compiler or build options.
In this case, confusion can be caused by the calling code passing in a 16-bit value, for example, and the receiving code expecting it to be 32 bits. If the top 16 bits of the passed-in value are left uninitialized, then bad things will happen.
You can work around this kind of issue by including a dummy entry in your enum to enforce a minimum size.
For example:
typedef enum {
FirstValue = 12,
SecondValue = 25,
DummyValue = 65536 // force enum to be greater than 16 bits
} MyEnum;
I'm pretty sure that a compiler that doesn't play nice with enum is an invalid compiler - enum is specified in the standard, so a failure to implement it means the compiler shouldn't technically be used to compile C (For the record, the scope of enumeration types is discussed in 6.2.1 and defined as a type in 6.2.5 (of C99), so one would assume that it's a valid part of the standard from thereon in)!
So no, I don't know of any such compilers.
I have a structure with no members (for the moment) and I would like to know if it is possible to suppress the warning I get:
warning: struct has no members
Is it possible to add a member and keep the sizeof the struct zero? Any other solution?
In c the behaviour of an empty structure is compiler dependent versus c++ where it is part of the spec (explanations here)
C++
A class with an empty sequence of members and base class objects is an empty class. Complete objects and member subobjects of an empty class type shall have nonzero size.
in C it is rather more murky since the c99 standard has some language which implies that truly empty structures aren't allowed (see TrayMan's answer) but many compilers do allow it (e.g gcc).
Since this is compiler dependent it is unlikely that you will get truly portable code in this case. As such non portable ways to suppress the warning may be your best bet.
In VS you would use #pragma warning
in GCC from 4.2.1 you have Diagnostic Pragmas
if you just need the struct symbol for casting and function arguments then just:
typedef struct _Interface Interface;
this will create the symbol for an opaque type.
Technically this isn't even valid C.
TrayMan was a little off in his analysis, yes 6.2.6.1 says:
Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined.
but tie that with 6.2.5-20, which says:
β A structure type describes a sequentially allocated nonempty set of member objects (and, in certain circumstances, an incomplete array), each of which has an optionally specified name and possibly distinct type.
and now you can conclude that structures are going to be one or more bytes because they can't be empty. Your code is giving you a warning, while the same code will actually fail to compile on Microsoft's Visual Studio with an error:
error C2016: C requires that a struct or union has at least one member
So the short answer is no, there isn't a portable way to avoid this warning, because it's telling you you're violating the C standards. You'll have to use a compiler specific extension to suppress it.
C99 standard is somewhat ambiguous on this, but seems to say that an empty struct should have non-zero size.
6.2.6.1
Except for bit-fields, objects are composed of contiguous sequences of one or more bytes,
the number, order, and encoding of which are either explicitly specified or
implementation-defined.
struct zero_information { int:0; };
The above code snippet will yield a non-zero value from sizeof(struct zero_information), but it might help you get what you looking for as 100% of all the storage that is allocated for it, is padding (only accessible through hacks, although I don't remember from the top of my head if acceding the padding is undefined behavior).
Is it possible to add a member and keep the sizeof the struct zero?
Nope. FWIW, C++ allows empty structs but the sizeof() is always non-zero for an empty struct.
Any other solution?
Not any easy ones. It's worth noting that empty structs are only somewhat supported in C and disallowed in C99.
Empty structs are supported in C++ but different compilers implement them with varying results (for sizeof and struct offsets), especially once you start throwing inheritance into the mix.
If you're not requiring "too strict" adherence, you might get away with this:
struct empty {
char nothing[0];
};
This is a GCC extension, though.
I was kind of hoping I'd be able to use the C99 feature called "flexible arrays", declared like this:
struct empty99
{
char nothing[]; // This is a C99 "flexible array".
};
but that doesn't work; they require that there is at least one normal struct member first, they can't be the only member.