Code Fragment: is this pure C? - c

I've got following code fragment and I want to know if it is pure C or it contains some C++ elements. This question stems from the fact that I think it is only C, but some compilers don't accept the code.
// User struct derived from FunctionBlock
struct Function{
// Inputs
int codeGenerationIterator;
int i;
char* s;
// Outputs
// Internal
};
void FunctionCall(struct Function *arg){
}
void FunctionConstructor(struct Function *arg){
arg->i=3;
arg->s="!";
// Call constructor for all not primitive variables
// Create struct with first call
FunctionCall(arg);
}
// User type definition
typedef struct Punto{
int codeGenerationIterator;
Function x[3+1];
Function *x_pointer[3+1];
double y;
};
void PuntoConstructor(struct Punto *arg){
// Call constructor for all not primitive variables
for(arg->codeGenerationIterator=0;arg->codeGenerationIterator<=3;arg->codeGenerationIterator++){
arg->x_pointer[arg->codeGenerationIterator]=&(arg->x[arg->codeGenerationIterator]);
FunctionConstructor(arg->x_pointer[arg->codeGenerationIterator]);
}
}
// User type definition
typedef struct Cerchio{
int codeGenerationIterator;
double r;
Punto centro;
Punto *centro_pointer;
};
void CerchioConstructor(struct Cerchio *arg){
// Call constructor for all not primitive variables
arg->centro_pointer=&(arg->centro);
PuntoConstructor(arg->centro_pointer);
}
// User type definition
typedef struct Container{
int codeGenerationIterator;
Cerchio circonferenza[10+1];
Cerchio *circonferenza_pointer[10+1];
};
void ContainerConstructor(struct Container *arg){
// Call constructor for all not primitive variables
for(arg->codeGenerationIterator=0;arg->codeGenerationIterator<=10;arg->codeGenerationIterator++){
arg->circonferenza_pointer[arg->codeGenerationIterator]=&(arg->circonferenza[arg->codeGenerationIterator]);
CerchioConstructor(arg->circonferenza_pointer[arg->codeGenerationIterator]);
}
}
int main(void){
// Variable definitions
int codeGenerationIterator;
int count;
Punto insiemePunti[50+1];
Punto *insiemePunti_pointer[50+1];
Cerchio cerchio;
Cerchio *cerchio_pointer;
Container container;
Container *container_pointer;
Container containers[11+1];
Container *containers_pointer[11+1];
// Call constructor for all not primitive variables
for(codeGenerationIterator=0;codeGenerationIterator<=50;codeGenerationIterator++){
insiemePunti_pointer[codeGenerationIterator]=&insiemePunti[codeGenerationIterator];
PuntoConstructor(insiemePunti_pointer[codeGenerationIterator]);
}
cerchio_pointer=&cerchio;
CerchioConstructor(cerchio_pointer);
container_pointer=&container;
ContainerConstructor(container_pointer);
for(codeGenerationIterator=0;codeGenerationIterator<=11;codeGenerationIterator++){
containers_pointer[codeGenerationIterator]=&containers[codeGenerationIterator];
ContainerConstructor(containers_pointer[codeGenerationIterator]);
}
container.circonferenza[1].centro.x[0].i=2;
containers[2].circonferenza[2].centro.x[4].i=2;
printf("Works!");
getchar();getchar(); // TODO: delete
return 0;
}
As you can see I haven't use classes or overloading but only simple instructions, structs and some pointers. So, why do some strict C compilers give me an error?

No, this is not valid C. This line:
Function x[3+1];
lacks the struct keyword, and there's no typedef struct Function Function; to introduce the type alias you seem to be using.
Also, the use of // comments requires a recent-enough compiler, that syntax wasn't added to C officially until C99. An older compiler would fail for this reason, too.

Some example of compilers are: "Miracle C", "Tiny C" and the error does not provide any information
Maybe try a real compiler then? How about just take your code and throw it in GCC to get better error messages.
Despite that fact, it sounds like you are getting error messages: "missing ';' at Probably just means something to the compiler looks like it should have been two statements and you forgot to break it up with a ;, it might not be the best error message, but no compiler can always tell you outright what's wrong, they're just hints becuase they expect you to be smarter. :)
You have a bunch of structs in your code:
typedef struct Cerchio {
typedef struct Punto {
struct Function{
One of these structs is not like the others.
If you use the typedef you can refer to the structure just by the name Cerchio (for example).
If you do not use typedef you need to explicitly call it everytime: struct Function

In addition to the missing struct keywords, your code must #include <stdio.h>. In C99 this is required in order to be a well-formed program. In C89 the program is well-formed without it (once the other errors are fixed) but has undefined behavior.
gcc -pedantic-errors -std=c99 will give you the exact line numbers that contain errors, and in addition gives some warnings that you should pay attention to. Your definitions like:
typedef struct Punto { ... };
are all wrong even though they're legal. The typedef has no effect since you don't provide a name for the type you're supposedly def-ing. So the only way to identify it in C is as struct Punto, not Punto as you'd like and as it can be identified in C++.

Related

C compiler checking of a typedef'ed void *

We have an anonymous type, typedefed to void *, which is the handle for an API (all code in C11). It is deliberately void * as what it is pointing to changes depending on the platform we are compiled for and we also don't want the application to try dereferencing it. Internally we know what it should be pointing to and we cast it appropriately. This is fine, the code is public, we've been using it for years, it cannot be changed.
The problem is that we now need to introduce another one of these, and we don't want the user to get the two confused, we want the compiler to throw an error if the wrong handle is passed to one of our functions. However, all of the versions of all of the C compilers I have tried so far (GCC, Clang, MSVC) don't care; they know that the underlying type is void * and so anything goes (this is with -Wall and -Werror). Putting it another way, our typedef has not achieved anything, we might as well have just used void *. I have also tried Lint and CodeChecker, who also don't seem to care (though you could probably question my configurations for these). Note that I am not able to use -Wpedantic as we include third party code where that wouldn't fly.
I have tried making the new thing a specific typedefed pointer rather than a void * but that doesn't entirely fix things as the compiler is still happy for the caller to pass that new specific typedefed pointer into the existing functions that are expecting the existing handle typedef.
Is there (a) a way to construct a new anonymous handle such that the compiler will not allow it to be passed to the existing functions or (b) a checker that we can apply to pick the problem up, at least in our own use of these APIs?
Here is some code to illustrate the problem:
#include <stdlib.h>
typedef struct {
int contents;
} existingThing_t;
typedef void *anonExistingHandle_t;
typedef struct {
char contents[10];
} newThing_t;
typedef void *anonNewHandle_t;
typedef newThing_t *newHandle_t;
static void functionExisting(anonExistingHandle_t handle)
{
existingThing_t *pThing = (existingThing_t *) handle;
// Perform the function
(void) pThing;
}
static void functionNew(anonNewHandle_t handle)
{
newThing_t *pThing = (newThing_t *) handle;
// Perform a new function
(void) pThing;
}
int main() {
anonExistingHandle_t existingHandle = NULL;
anonNewHandle_t newHandleA = NULL;
newHandle_t newHandleB = NULL;
functionExisting(existingHandle);
functionNew(newHandleA);
// These should result in a compilation error
functionExisting(newHandleA);
functionNew(existingHandle);
functionExisting(newHandleB);
return 0;
}
Is there (a) a way to construct a new anonymous handle such that the compiler will not allow it to be passed to the existing functions
Yes, use a type that can't be implicitly converted to void *. Use a structure.
typedef struct {
struct newThing_s *p;
} anonNewHandle_t;
Anyway, your design is just flawed and disables all static compiler checks. Do not use void *, instead use structures or structures with void * inside, to enable compile checks. Research how the very, very standard FILE * works. FILE is not void.
Do not use typedef pointers. They are very confusing. https://wiki.sei.cmu.edu/confluence/display/c/DCL05-C.+Use+typedefs+of+non-pointer+types+only
I suggest rewriting your library so that you do not use void * and do not use typedef pointers.
The design, may look like the following:
// handle.h
struct handle_s;
typedef struct {
struct handle_s *p;
} handle_t;
handle_t handle_init(void);
void handle_deinit(handle_t t);
void handle_do_something(handle_t t);
// handle.c
struct handle_s {
int the_stuff_you_need;
};
handle_t handle_init(void) {
return (handle_t){
.p = calloc(1, sizeof(struct handle_s))
};
}
void handle_do_something(handle_t h) {
struct hadnle_s *t = h->p;
// etc.
}
// anotherhandle.h
// similar to above
typedef struct {
struct anotherhandle_s *p;
} anotherhandle_t;
void anotherhandle_do_something(anotherhandle_t h);
// main
int main() {
handle_t h = handle_new();
handle_do_something(h);
handle_free(h);
anotherhandle_do_something(h); // compiler error
}

OOP and forward declaration of structure in C

I am studying C language and have recently learned how to write the OOP using C. Most part of it was not hard that much to understand for me except the name of structures type used to create new class.
My textbook used struct dummy_t for forward declaration and typedef struct {...} dummy_t for its definition. In my understanding, these are two different type because the former is struct dummy type and the later is struct type without a name tag but the sample code from the textbook worked well.
So I deliberately modified the sample code so that the difference in the names of structures will be much clearer. Below are the lines of code I tried.
//class.h
struct test_a;
struct test_a * test_init(void);
void test_print(struct test_a*);
//class.c
#include <stdio.h>
#include <stdlib.h>
typedef struct dummy{
int x;
int y;
} test_b;
test_b * test_init(void){
test_b * temp = (test_b *) malloc(sizeof(test_b));
temp->x = 10;
temp->y = 11;
return temp;
}
void test_print(test_b* obj){
printf("x: %d, y: %d\n", obj->x, obj->y);
}
//main.c
#include "class.h"
int main(void){
struct test_a * obj;
obj = test_init();
test_print(obj);
return 0;
}
// It printed "x: 10, y: 10"
As you can see, I used struct test_a for forward declaration and typedef struct dummy {...} test_b for definition.
I am wondering why I did not get the compile error and it worked.
I am wondering why I did not get the compile error
When you compile main.c the compiler is told via a forward declaration from class.h that there is a function with the signature struct test_a * test_init(void);
The compiler can't do anything other than just trusting that, i.e. no errors, no warnings can be issued.
When you compile class.c there is no forward declaration but only the function definition, i.e. no errors, no warnings.
It's always a good idea to include the .h file into the corresponding .c file. Had you had a #include "class.h" in class.c the compiler would have been able to detect the mismatch.
..and it worked
What happens is:
A pointer to test_b is assigned to a pointer to test_a variable
The variable is then passed as argument to a function expecting a pointer to test_b
So once you use the pointer it is used as it was created (i.e. as pointer to test_b). In between you just stored in a variable of another pointer type.
Is that ok? No
Storing a pointer to one type in a object defined for another pointer type is not ok. It's undefined behavior. In this case it "just happened to work". In real life it will "just happen to work" on most systems because most systems use the same pointer layout for all types. But according to the C standard it's undefined behavior.
It 'worked' because you did not include class.h in class.c. So the compiler can't see the implementation does not match the declaration.
The proper way is (but without the typedef for clarity):
// class.h
struct test_a;
struct test_a* test_init(void);
//class.c
#include "class.h"
struct test_a {
int x;
int y;
};
struct test_a* test_init(void)
{
...
}
The struct test_a in the header file makes the name test_a known to the compiler as being a struct. But as it does not now what is in the struct you can only use pointers to such a struct.
The members are defined in the implementation file and can only be used there.
If you want to use a typedef:
// header
typedef struct test_a_struct test_a;
test_a* test_init(void);
//implementation
struct test_a_struct {
int x;
int y;
};
test_a* test_init(void)
{
...
}

How does linking work in C with regards to opaque pointers?

So, I've been having a bit of confusion regarding linking of various things. For this question I'm going to focus on opaque pointers.
I'll illustrate my confusion with an example. Let's say I have these three files:
main.c
#include <stdio.h>
#include "obj.h" //this directive is replaced with the code in obj.h
int main()
{
myobj = make_obj();
setid(myobj, 6);
int i = getid(myobj);
printf("ID: %i\n",i);
getchar();
return 0;
}
obj.c
#include <stdlib.h>
struct obj{
int id;
};
struct obj *make_obj(void){
return calloc(1, sizeof(struct obj));
};
void setid(struct obj *o, int i){
o->id = i;
};
int getid(struct obj *o){
return o->id;
};
obj.h
struct obj;
struct obj *make_obj(void);
void setid(struct obj *o, int i);
int getid(struct obj *o);
struct obj *myobj;
Because of the preprocessor directives, these would essentially become two files:
(I know technically stdio.h and stdlib.h would have their code replace the preprocessor directives, but I didn't bother to replace them for the sake of readability)
main.c
#include <stdio.h>
//obj.h
struct obj;
struct obj *make_obj(void);
void setid(struct obj *o, int i);
int getid(struct obj *o);
struct obj *myobj;
int main()
{
myobj = make_obj();
setid(myobj, 6);
int i = getid(myobj);
printf("ID: %i\n",i);
getchar();
return 0;
}
obj.c
#include <stdlib.h>
struct obj{
int id;
};
struct obj *make_obj(void){
return calloc(1, sizeof(struct obj));
};
void setid(struct obj *o, int i){
o->id = i;
};
int getid(struct obj *o){
return o->id;
};
Now here's where I get a bit confused. If I try to make a struct obj in main.c, I get an incomplete type error, even though main.c has the declaration struct obj;.
Even if I change the code up to use extern, It sill won't compile:
main.c
#include <stdio.h>
extern struct obj;
int main()
{
struct obj myobj;
myobj.id = 5;
int i = myobj.id;
printf("ID: %i\n",i);
getchar();
return 0;
}
obj.c
#include <stdlib.h>
struct obj{
int id;
};
So far as I can tell, main.c and obj.c do not communicate structs (unlike functions or variables for some which just need a declaration in the other file).
So, main.c has no link with struct obj types, but for some reason, in the previous example, it was able to create a pointer to one just fine struct obj *myobj;. How, why? I feel like I'm missing some vital piece of information. What are the rules regarding what can or can't go from one .c file to another?
ADDENDUM
To address the possible duplicate, I must emphasize, I'm not asking what an opaque pointer is but how it functions with regards to files linking.
Converting comments into a semi-coherent answer.
The problems with the second main.c arise because it does not have the details of struct obj; it knows that the type exists, but it knows nothing about what it contains. You can create and use pointers to struct obj; you cannot dereference those pointers, not even to copy the structure, let alone access data within the structure, because it is not known how big it is. That's why you have the functions in obj.c. They provide the services you need — object allocation, release, access to and modification of the contents (except that the object release is missing; maybe free(obj); is OK, but it's best to provide a 'destructor').
Note that obj.c should include obj.h to ensure consistency between obj.c and main.c — even if you use opaque pointers.
I'm not 100% what you mean by 'ensuring consistency'; what does that entail and why is it important?
At the moment, you could have struct obj *make_obj(int initializer) { … } in obj.c, but because you don't include obj.h in obj.c, the compiler can't tell you that your code in main.c will call it without the initializer — leading to quasi-random (indeterminate) values being used to 'initialize' the structure. If you include obj.h in obj.c, the discrepancy between the declaration in the header and the definition in the source file will be reported by the compiler and the code won't compile. The code in main.c wouldn't compile either — once the header is fixed. The header files are the 'glue' that hold the system together, ensuring consistency between the function definition and the places that use the function (references). The declaration in the header ensures that they're all consistent.
Also, I thought the whole reason why pointers are type-specific was because the pointers need the size which can vary depending on the type. How can a pointer be to something of unknown size?
As to why you can have pointers to types without knowing all the details, it is an important feature of C that provides for the interworking of separately compiled modules. All pointers to structures (of any type) must have the same size and alignment requirements. You can specify that the structure type exists by simply saying struct WhatEver; where appropriate. That's usually at file scope, not inside a function; there are complex rules for defining (or possibly redefining) structure types inside functions. And you can then use pointers to that type without more information for the compiler.
Without the detailed body of the structure (struct WhatEver { … };, where the braces and the content in between them are crucial), you cannot access what's in the structure, or create variables of type struct WhatEver — but you can create pointers (struct WhatEver *ptr = NULL;). This is important for 'type safety'. Avoid void * as a universal pointer type when you can, and you usually can avoid it — not always, but usually.
Oh okay, so the obj.h in obj.c is a means of ensuring the prototype being used matches the definition, by causing an error message if they don't.
Yes.
I'm still not entirely following in terms of all pointers having the same size and alignment. Wouldn't the size and alignment of a struct be unique to that particular struct?
The structures are all different, but the pointers to them are all the same size.
And the pointers can be the same size because struct pointers can't be dereferenced, so they don't need specific sizes?
If the compiler knows the details of the structure (there's a definition of the structure type with the { … } part present), then the pointer can be dereferenced (and variables of the structure type can be defined, as well as pointers to it, of course). If the compiler doesn't know the details, you can only define (and use) pointers to the type.
Also, out of curiosity, why would one avoid void * as a universal pointer?
You avoid void * because you lose all type safety. If you have the declaration:
extern void *delicate_and_dangerous(void *vptr);
then the compiler can't complain if you write the calls:
bool *bptr = delicate_and_dangerous(stdin);
struct AnyThing *aptr = delicate_and_dangerous(argv[1]);
If you have the declaration:
extern struct SpecialCase *delicate_and_dangerous(struct UnusualDevice *udptr);
then the compiler will tell you when you call it with a wrong pointer type, such as stdin (a FILE *) or argv[1] (a char * if you're in main()), etc. or if you assign to the wrong type of pointer variable.

How to capture a struct declaration in function

I have the following c code:
struct {
short s;
int n;
} variableName;
I want to write a function to capture this variable like so
void func(MyStruct* var){
//do stuff
}
func(&variableName);
I would like to do this without providing a definition for the struct. Is there a way to capture variableName?
No, you can't pass an "anonymous" struct into a function in C. You could of course define your function to accept the arguments individually:
void func(short s, int n) { ... }
Or you can define the MyStruct structure in a place that both the function and the calling code has visibility to. Note that the whole struct is passed by value (copy) when you do that, which may be the behavior you want here (or may not be).
You may be looking for something more like a "dictionary" or "associative array" or "hash" type that many other languages provide, with arbitrary key value pairs in it. Pure C does not have a facility for this; the compiler wants to know the layout of a structure in advance.
(I'm not sure if you might be asking about a slightly more esoteric idea, which is hiding the composition of a structure and passing around an "opaque handle" out of and into an API. There are ways to structure that in C, but please say so if that's what you're talking about.)
Completely overlooked "I would like to do this without providing a definition for the struct. Is there a way to capture variableName?" in the OP, unless it was edited after. The question makes less sense now, but heres how you could normally pass a struct to a function for future readers.
#include <stdio.h>
struct StructName{
short s;
int n;
};
void func(struct StructName struct_var){
printf("Param values are: %4X %4X\n", struct_var.s & 0xFFFF, struct_var.n & 0xFFFF);
}
int main(){
struct StructName struct_var;
struct_var.s = 0xDEAD;
struct_var.n = 0xBEEF;
func(struct_var);
}
//It looks like you are trying to use the definition as a variable. Here the definition is StructName and the variable is struct_var.
this sample code outputs:
Param values are: DEAD BEEF
If you use clang or gcc, you may be able to use typeof:
struct foo {
struct {
int i;
} anon;
} foo;
void do_something(typeof(foo.anon)* member) {
member->i = 1;
}
If there is no global instance of your type, you may be able to use typeof((struct foo){}.anon).
This comes with a lot of downsides. The most obvious ones are that:
it's not standard, and it ties you to clang/gcc
it's pretty darn ugly
it might not behave as you expect anyway
For instance, structurally-equivalent anonymous types do not have the same type, so in something like this:
struct foo {
struct {
int i;
} anon1;
struct {
int i;
} anon2;
} foo;
anon1 and anon2 both have a different type, meaning that typeof one of them cannot be used to refer to both.
In the long run, you will almost certainly find that it's worth naming the structures, especially if you use them as function arguments. For instance, if you want to make your variable available from a header, I think that you'll have to work pretty hard to keep it anonymous.
Although it's not particularly pretty and not compatible with C++, C puts the name of nested declarations in the global namespace, so this is portable and it's not a very big code change to front-load:
struct {
struct not_anon {
int i;
} anon;
} foo;
void do_something(struct not_anon* member) {
member->i = 1;
}

Co-Dependent Definitions in C

Suppose we have a function pointer on a struct, which has the struct itself as the first argument, a typical callback scenario.
typedef void (*callback_type)(my_struct_type *mst, int whatever);
typedef struct {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;
This produces a compiler error on the first typedef, as one might expect. error: unknown type name my_struct_type. Reversing the definitions produces the same result, but the unknown type is callback_type.
The easy solution is to do the following:
typedef struct my_struct_type_S {
// lots of fun stuff
void (*notify_me)(my_struct_type_S *mst, int whatever);
} my_struct_type;
However, doing this elides the function pointer type definition, which it would be nice to be able to easily refer to later, and use for static type checks, nice error messages, etc.
Any suggestions on how to resolve this?
Edit on "possible duplicate":
This scenario involves function pointer typedefs that are arcane to many people. I think this is a good example for that case, and additionally, the accepted answer is very clean, clear, and simple.
You can do this by giving the struct a tag and using a forward declaration of the struct. Then you can use the typedef for the function pointer, and subsequently complete the definition of the struct.
typedef struct my_struct_type_S my_struct_type;
typedef void (*callback_type)(my_struct_type *mst, int whatever);
struct my_struct_type_S {
// lots of fun stuff
callback_type notify_me;
};
You need to define the tag of the struct
typedef void (*callback_type)(struct _my_struct_type *mst, int whatever);
typedef struct _my_struct_type {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;

Resources