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)
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)
{
//...
}
In my project, a structre is being used in several functions.
like this:
void function1 (Struct_type1 * pstType1);
but when I search for Struct_type1 's references, I can't find any. This Structure must be defined somewhere. How to find the definition?
OS- Windows
Edit: I think its difficult to answer this without source code and I can't share that big project here. So, I've changed my question to:
Is Hidden Declaration possible in an embedded project?
(by hidden I mean no one can see the definition.)
Is Hidden Declaration possible in an embedded project?
If you have access to all source code in the project, then no.
This is only possible in one specific case, and that is when you have an external library for which you don't have the C code, you only have a header file and an object file or lib file (or DLL etc).
For such cases it is possible (and good practice) for the library header to forward-declare an incomplete type in the header, and hide the actual implementation in the C file which you don't have access to.
You would then have something like this in the h file:
typedef struct Struct_type1 Struct_type1;
The compiler might often do things like this with its own libraries too, if they want to hide away the implementation. One such example is the FILE struct.
Not an answer, but possibly a way to find the answer. Idea: Let compiler help you.
Define the struct yourself, then look at compiler errors like "struct struct_type1 is already defined in... at line ..."
If you get no compiler error in this case, maybe the struct is only forward declared, but not defined.
To explain why this is sometimes done, here a bit of code:
// Something.h
struct struct_type1; // Forward declaration.
struct struct_type1 *SomethingInit();
void SomethingDo( struct struct_type1 * context );
In code looking like the above, the definition of the struct is hidden inside the implementation. On the outside, it need not be known, how the struct is defined or its size etc, as it is only traded as a pointer to the struct (and never as a value). This technique is used to keep internal types out of public header files and used often by library designers. You can think of it as an opaque handle of sorts.
But then, you still should be able to find the forward declaration, albeit not the definition.
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.
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.
I was just going through the c-faq, when I came across this page. I stated that the following program will have a core dump:
struct list {
char *item;
struct list *next;
}
/* Here is the main program. */
main(argc, argv)
{}
The reason they told for the core dump to happen was:
A missing semicolon at the end of the structure declaration causes main to be declared as returning a structure. (The connection is hard to see because of the intervening comment.) Since structure-valued functions are usually implemented by adding a hidden return pointer (see question 2.9), the generated code for main() tries to accept three arguments, although only two are passed (in this case, by the C start-up code). See also questions 10.9 and 16.4.
Although, when I ran this program online over here, it worked perfectly and the program did run till the end. Also, when I compiled this program using gcc, I got no warnings.
I was surprised, as the program should have not runned till the end. Can someone tell me why this program works? If it is correct, why is it mentioned that the program will not work (any chance it might crash?).
NOTE: Please do not post comments such as use int main because I have just copy pasted the code, and in actual, I use the proper way.
This is a misreading of the C FAQ.
The C FAQ explains why the code is incorrect, but it does not say that the code is guaranteed to crash. Here's part of the section you quoted:
Since structure-valued functions are usually implemented by adding a hidden return pointer...
I've added emphasis. The C FAQ is explaining why the code might crash. The code is incorrect in either case. (In theory, the behavior could be implementation-defined, but it is extremely unlikely that your C implementation defines what happens in this case.)
On many systems (ABIs), functions which return structures will use registers for the return value if the structures are small enough. I don't know what the limit is for common x64 ABIs, but two words (two pointers) is fairly small.
This program does not appear to be illegal according to the standard.
Lets look at the program first cleaned up:
struct list {
char *item;
struct list *next;
} main(argc, argv){}
Ok, so we are declaring main as returning a struct list.
Let us now look at the valid declarations of main according to ISO 9899:2011
(C11) though C99 is largely the same.
It shall be defined with a return type of int and with no parameters
or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared). or in some other implementation-defined manner.
(Slightly abridged)
It appears to me that this therefore squarely falls into the third definition of "some other implementation-defined manner" meaning it is in the realm of implementation defined behavior.
Therefore this is not an issue of C at all but instead up to the compiler in use and thus largely irrelevant to a C faq. You would need to look into your compiler's documentation for what (if anything) this is defined to do.
Most likely your compiler does not define it at all in which case it is undefined and could thus result in any behavior at all including appearing to work or crashing.