I want to get the size of a specific member in a struct.
sizeof(((SomeStruct *) 0)->some_member) works for me but I feel like there might be a nicer way to do it.
I could #define SIZEOF_ELEM(STRUCT, ELEM) sizeof(((STRUCT *) 0)->ELEM) and then use SIZEOF_ELEM(SomeStruct, some_member), but I wonder whether there is already something better built-in.
My specific use-case is in hsc2hs (Haskell C bindings).
pokeArray (plusPtr context (#offset AVFormatContext, filename)) .
take (#size ((AVFormatContext *) 0)->filename) .
(++ repeat '\NUL') $ filename
What you've got is about as clean as it gets if you can't guarantee you have a variable to dereference. (If you can, then use just sizeof(var.member) or sizeof(ptr->member), of course, but this won't work in some contexts where a compile-time constant is needed.)
Once upon a long, long time ago (circa 1990), I ran into a compiler that had 'offsetof' defined using the base address 0, and it crashed. I worked around the problem by hacking <stddef.h> to use 1024 instead of 0. But you should not run into such problems now.
Microsoft has the following in one of their headers:
#define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
I see no reason to do any different.
They have related macros for:
RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()
and the nifty:
CONTAINING_RECORD()
which helps implement generic lists in straight C without having to require that link fields be at the start of a struct. See this Kernel Mustard article for details.
I believe you've already got the correct solution there. You could dig up your stddef.h and look for how offsetof is defined, since it does a very similar thing.
Remember that there may well be a difference between the sizeof a member and the difference between the offsetofs of that member and the next one, due to padding.
In C++ you could do sizeof(SomeStruct::some_member), but this is c and you have no scope resolution operator. What you've written is as good as can be written, as far as I know.
Related
When developing and maintaining code, I add a new member to a structure and sometimes forget to add the code to initialize or free it which may later result in a memory leak, an ineffective assertion, or run-time memory corruption.
I try to maintain symmetry in the code where things of the same type are structured and named in a similar manner, which works for matching Construct() and Deconstruct() code but because structures are defined in separate files I can't seem to align their definitions with the functions.
Question: is there a way through coding to make myself more aware that I (or someone else) has changed a structure and functions need updating?
Efforts:
The simple:
-Have improved code organization to help minimize the problem
-Have worked to get into the habit of updating everything at once
-Have used comments to document struct members, but this just means results in duplication
-Do use IDE's auto-suggest to take a look and compare suggested entries to implemented code, but this doesn't detect changes.
I had thought that maybe structure definitions could appear multiple times as long as they were identical, but that doesn't compile. I believe duplicate structure names can appear as long as they do not share visibility.
The most effective thing I've come up with is to use a compile time assertion:
static_assert(sizeof(struct Foobar) == 128, "Foobar structure size changed, reevaluate construct and destroy functions");
It's pretty good, definitely good enough. I don't mind updating the constant when modifying the struct. Unfortunately compile time assertions are very platform (compiler) and C Standard dependent, and I'm trying to maintain the backwards compatibility and cross platform compatibility of my code.
This is a good link regarding C Compile Time Assertions:
http://www.pixelbeat.org/programming/gcc/static_assert.html
Edit:
I just had a thought; although a structure definition can't easily be relocated to a source file (unless it does not need to be shared with other source files), I believe a function can actually be relocated to a header file by inlining it.
That seems like a hacked way to make the language serve my unintended purpose, which is not what I want. I want to be professional. If the professional practice is not to approach this code-maintainability issue this way, then that is the answer.
I've been programming in C for almost 40 years, and I don't know of a good solution to this problem.
In some circles it's popular to use a set of carefully-contrived macro definitions so that you can write the structure once, not as a direct C struct declaration but as a sequence of these macros and then, by defining the macro differently and re-expanding, turn your "definition" into either a declaration or a definition or an initialization. Personally, I feel that these techniques are too obfuscatory and are more trouble than they're worth, but they can be used to decent effect.
Otherwise, the only solution -- though it's not what you're looking for -- is "Be careful."
In an ideal project (although I realize full well there's no such thing) you can define your data structures first, and then spend the rest of your time writing and debugging the code that uses them. If you never have occasion to add fields to structs, then obviously you won't have this problem. (I'm sorry if this sounds like a facetious or unhelpful comment, but I think it's part of the reason that I, just as #CoffeeTableEspresso mentioned in a comment, tend not to have too many problems like this in practice.)
It's perhaps worth noting that C++ has more or less the same problem. My biggest wishlist feature in C++ was always that it would be possible to initialize class members in the class declaration. (Actually, I think I've heard that a recent revision to the C++ standard does allow this -- in which case another not-necessarily-helpful answer to your question is "Use C++ instead".)
C doesn't let you have benign struct redefinitions but it does let you have benign macro redefinitions.
So as long as you
save the struct body in a macro (according to a fixed naming convention)
redefine the macro at the point of your constructor
you will get a warning if the struct body changes and you haven't updated the corresponding constructor.
Example:
header.h:
#define MC_foo_bod \
int x; \
double y; \
void *p
struct foo{ MC_foo_bod; };
foo__init.c
#include "header.h"
#ifdef MC_foo_bod
//try for a silent redefinition
//if it wasn't silent, the macro changed and so should this code
#define MC_foo_bod \
int x; \
double y; \
void *p
#else
#error ""
//oops--not a redefinition
//perhaps a typo in the macro name or a failure to include the header?
#endif
void foo__init(struct foo*X)
{
//...
}
This is from a textbook:
/* This function locates the address of where a new structure
should be inserted within an existing list.
It receives the address of a name and returns the address of a
structure of type NameRec
*/
struct NameRec *linear Locate(char *name)
{
...
}
I understand it returns a pointer to a struct NameRec. Why is "linear" there and why is there a space between "linear" and "Locate"?
#define linear
will make it syntactically correct even if it wasn't before (though, technically, you'd probably want a #undef linear beforehand to avoid possible conflicting macro definitions).
It depends entirely on the context of the code, which you haven't shown. As it stands now, with no header inclusions or definitions like -Dlinear= on the compiler command line, it would not compile in a standards-conformant environment without extensions.
The best way to tell, of course, is to just try to actually compile the thing and see what happens :-)
Given that the solutions link for chapter 13 (the one you're asking about) has no mention of the linear word in the solution, I'd say it's a safe bet to assume your book is incorrect. I'd consider contacting the author (apparently currently working at FDU in New Jersey) to clear it up.
It's a typo in the book. See the locate function here:
https://users.ipfw.edu/chansavj/ACY2017/ANSI_C/ANSI_C_4thEd/Solutions%20to%20Exercises%20(Windows)/Solutions/83556-0s/Ch13/pgm13-5ex3.c
(Posted by ta.speot.is in the comments)
I have to return nul in a function but I'm not allowed to include any library. I tried to find in how is NULL defined, then to sys/_types/_null.h only to find that NULL is actually __DARWIN_NULL. Great ! Now, I have no idea where to search in order to find the __DARWIN_NULL definition...
I have to return nul in a function but I'm not allowed to include any library.
The solution to this problem is far simpler than you're making it; you've actually asked a form of XY problem.
You won't find the NUL character defined in any standard library; the best way to return that will be using the constant '\0' or 0.
If your professor is teaching you to avoid using <stddef.h> to find NULL then he/she has set a silly exercise which involves using something other than the most appropriate tool for the job, a tool which is guaranteed by the standard to exist, by the way... I would be raising this as a concern.
Nonetheless, sometimes professors don't care and will teach you to do stupid things anyway. NULL is defined as an implementation-defined null pointer constant, usually 0 or a conversion of 0 to void * like so: ((void *) 0). That may not be the implementation-defined value your NULL resolves to; in that case, adjust to suit :)
You could add a preprocessor definition such as #define NULL ((void *) 0) and then you would be able to return NULL; from your functions. Ta-da! Stupid exercises deserve stupid solutions.
If your professor says you're not allowed to use #define, either, I would be tempted to ask him what you are allowed to use. Changing requirements on the fly is not fair. Most compilers will allow you to set preprocessor constants using a command line argument, for example cc -DNULL='((void *) 0)' .... This is useful for exposing compile-time configuration options, but again, using this to define NULL is dumb.
The question in your title is different to the rest of your post. __DARWIN_NULL could also be defined using either of the above, providing it isn't already defined, but I really don't think that's required to answer your actual question.
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.
We are all familiar with working of sizeof operator in C language. I am trying to make a similar working function that will absorb any kind of datatype and return me its size.
Can somebody tell me how to make such a similar function in "C".
int myOwnSizeOf(/*what would be parameter type?*/)
{
//and what about the definition?
}
Thanks
You can't do that with a function. That's why sizeof is an operator built into the language, not a library function. It's magic.
You could do
#define myOwnSizeOf(x) (sizeof(x))
but I don't really see the point.
Since a function is evaluated at runtime, it can never consume a datatype but only objects. That's why sizeof is a built in operator.
You might get it to work for this limited case in C++ with a template function. But in C your only possibilities to consume an object of any datatype are either void pointers or macros. But the former won't work, of course, as it looses any type information and the latter was already suggested by aschepler and as he noted, it won't buy you anything (and it isn't a function, anyway).
A function can't do it, but a macro can, if you don't mind throwing in a little technical UB that can't/won't really matter:
#define mysizeof(T) (size_t)((char *)((T*)0+1)-(char *)0)
If you replaced 0 with the address of a static-storage-duration object larger than any other object you'd ever try to take the size of, the UB would go away.
Edit: Note that this is for types T; a version for variables is much easier:
#define mysizeof(v) (size_t)((char *)(&v+1)-(char *)&v)