VSCode reports an incomplete type is not allowed error when trying to use struct ip.
I know this is a problem with intellisense as my program compiles just fine using gcc monitor.c -o monitor -lnet so there isn't an actual error, but intellisense seems to disagree.
Here is the minimal code to get the error:
#include <netinet/ip.h>
#include <stdlib.h>
int main()
{
struct ip * my_ip = (struct ip *) malloc(sizeof(struct ip));
}
I tried adding /usr/include/** to the c_cpp_propertied.json file.
Taking a look into the ip.h file directly I can see that the struct definition is "hidden" inside an #ifdef __USE_MISC so I added that to the defines section of c_cpp_propertied.json with no luck.
I'm fresh out of ideas and I haven't been able to find anything related to the issue. Nothing helpful anyway.
Taking a look into the ip.h file directly I can see that the struct definition is "hidden" inside an #ifdef __USE_MISC so I added that to the defines section of c_cpp_propertied.json with no luck.
According to this you can try to do following in your example:
#ifndef __USE_MISC
#define __USE_MISC
#endif // __USE_MISC
#include <netinet/ip.h>
#include <stdlib.h>
int main()
{
struct ip * my_ip = (struct ip *) malloc(sizeof(struct ip));
}
Explanation: You mentioned that struct is hidden in #ifdef __USE_MISC preprocessor condition. Which means it's only visible if somewhere in your code before this file the definition #define __USE_MISC exists, or if this definiton is passed via compiler flags. Seems like VSCode C/C++ Intellisense isn't doing this, while gcc does
P.S. Also, please take a look at what does this macro means and what does it used for: link
P.P.S. After further investigation was found that OP has no _DEFAULT_SOURCE definition defined in his compiler flags/source files.
So, the actual answer is to add following snippet of code before includes (or to the compiler flags or IDE settings):
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif // _DEFAULT_SOURCE
#include <netinet/ip.h>
// ...
Related
I keep running into an issue while trying to include an enumeration from one header file in antoher.
The environment I am working in is embedded C using IAR Embedded Workbench.
I have a header file for dedicated enumerated types named "enums.h"
#ifndef ENUMS_H_
#define ENUMS_H_
typedef enum
{
SET,
SCHEDULE,
EXECUTE
}action_type_t;
#endif
and a header file for a parser named "parser.h"
#ifndef PARSER_H_
#define PARSER_H_
#include "enums.h"
#include <stdint.h>
typedef struct
{
action_type_t action;
uint16_t nbytes;
}Message;
#endif
In parser.c I include the header as
#include "parser.h"
When I compile this, I get the error "identifier action_type_t is undefined"
What am I doing wrong here? I am stumped at this point.
Thank you
Your enum definition is missing commas, your parser.h uses uint16_t while having failed to include <stdint.h> and, to be extra pedantic, your include guard macro is encroaching on the reserved namespace because it starts with _ and a capital letter.
This should work:
enums.h:
#ifndef ENUMS_H_
#define ENUMS_H_
typedef enum
{
SET,
SCHEDULE,
EXECUTE, /*the last comma is optional*/
}action_type_t;
#endif
parser.h:
#ifndef PARSER_H_
#define PARSER_H_
#include "enums.h"
#include <stdint.h>
typedef struct
{
action_type_t action;
uint16_t nbytes;
}Message;
#endif
Thank you to all who answered, I figured I would come back and close this one.
It turns out I had an identically named, but empty header file included in my project...
Next time i'll be better about looking in my own backyard first before asking others.
However PSkocik did provide a working example, and his code compiles perfectly for anyone who stumbles into this thread!
I'm trying to figure out, how to use C headers with #ifndef and #include.
Lets say I have these two header files:
headerA.h:
#ifndef HEADERA_H
#define HEADERA_H
#include "headerB.h"
typedef int MyInt;
TFoo foo;
... some other structures from headerB.h ...
#endif
headerB.h
#ifndef HEADERB_H
#define HEADERB_H
#include "headerA.h"
typedef struct foo{
MyInt x;
} TFoo;
#endif
headerA.c
#include "headerA.h"
... some code ...
headerB.c
#include "headerB.h"
... some code ...
When compiling headerB.c, it says
In file included from headerB.h,
from headerB.c:
headerA.h: error: unknown type name ‘MyInt’
I think, it's becouse when headerB.h is compiling, it defines HEADERB_H and then, when headerA.h wants to include headerB.h, the #ifndef HEADERA_H is false = skips including.
What is the best practice here? I just read, that best practice is to do all #include directives in header files, but in this situation it looks like a problem.
EDIT: Ok, sorry for misleading you. This is just and example from bigger project with more files.
You have a circular dependency. Header file headerA.h depends on headerB.h which depends on headerA.h and so on and on.
You need to break that dependency, for example by not including headerB.h in headerA.h. It's not needed (nothing in headerA.h needs anything from headerB.h).
If you have to include headerB.h (as stated in your recent edit) then you first should reconsider how you use your header files, and what definition you place where. Perhaps move the definition of MyInt to headerB.h? Or have more header files, like one for type-aliases (like your MyInt which I personally see no use for), one for structures and one for variable declarations?
If that's not possible then you could try by changing the order of definitions and the include, like
#ifndef HEADERA_H
#define HEADERA_H
// Define type alias first, and other things needed by headerB.h
typedef int MyInt;
// Then include the header file needing the above definitions
#include "headerB.h"
TFoo foo;
... some other structures from headerB.h ...
#endif
Just drop the line
#include "headerB.h"
from file headerA.h
I have a weird problem with my C-Code that I don't really understand.
I have two header files os_memory.h and os_mem_drivers.h.
os_memory.h
#ifndef OS_MEMORY_H_
#define OS_MEMORY_H_
#include "lcd.h"
#include "os_mem_drivers.h"
static const MemAddr gui_alloc_table_start = 0x1C8;
#endif /* OS_MEMORY_H_ */
os_mem_drivers.h
#ifndef OS_MEM_DRIVERS_H_
#define OS_MEM_DRIVERS_H_
#include "os_memory.h"
#include "defines.h"
#include "os_core.h"
typedef uint16_t MemAddr;
#endif
If I try to compile this code the compiler gives me the error unknown type name 'MemAddr'. I don't get it because I included the right header files in each .h file so there shouldn't be any error.
Is there anything that I'm missing here?
I'm using AtmelStudio 6.1 and the C language for this project.
You should move the definition for type MemAddr before including "os_memory.h":
os_mem_drivers.h:
#ifndef OS_MEM_DRIVERS_H_
#define OS_MEM_DRIVERS_H_
#include <stdint.h>
typedef uint16_t MemAddr;
#include "os_memory.h"
#include "defines.h"
#include "os_core.h"
#endif
But a more important problem is the circular inclusion of "os_memory.h" and "os_mem_drivers.h". Each one includes the other: include guards prevent recursive inclusion but make it difficult to understand what is really going on. You should try and fix this issue.
I have a confusion about external structs. I have to define a global instance of the struct in a file other than which the struct is defined (as a RAM variable which I do not know what it is exactly).
Below is an example that GCC can compile and it runs correct while Code Composer Studio gives compile-time errors.
I want to learn where the problem is, how GCC can compile, and where/how I should use the extern declaration.
Any comment would be appreciated.
person.h
#ifndef PERSON_H
#define PERSON_H
struct person {
int age;
};
typedef struct person PERSON;
void modifyPerson();
#endif // PERSON_H
personRam.h
#ifndef PERSONRAM_H
#define PERSONRAM_H
#include "person.h"
PERSON p1;
#endif // PERSONRAM_H
modifyPerson.c
#include "person.h"
#include "personRam.h"
void modifyPerson() {
p1.age = 10;
}
main.c
#include <stdio.h>
#include "person.h"
#include "personRam.h"
int main() {
modifyPerson();
printf("%d", p1.age);
return 0;
}
You should not get a compiler error, but a linker error, saying that p1 is defined multiple times. At least that's what I guess is the problem.
The reason is that you define the variable in a header file, which you then include in multiple source files. This means that the definition is in both source files (The preprocessor #include directive literally puts the contents of the header file in place of the include "statement").
If you declare the variable as extern in the header file, and define it in one source file it should work.
So in personRam.h
extern PERSON p1;
And in one of the source files:
PERSON p1;
On which operating system are you compiling, and for which target system?
For what it is worth, Linux (& Unix-es) and Windows have different linking semantics.
Read Levine's "Linkers & Loaders" book for details.
I'm just getting started with modular programming in C. I think I'm doing something wrong with the inclusions, because I'm getting a lot of conflicting types for 'functionName' and previous declaration of 'functionName' was here errors. I did put inclusion guards in place.
Do you know a clear tutorial that explains modular programming in C, especially how the inclusions work?
Update: I have tried to isolate my issue. Here's some code, as requested.
Update 2: updated code is below. The errors have been updated, too.
/*
* main.c
*/
#include <stdio.h>
#include "aStruct.h"
int main() {
aStruct asTest = createStruct();
return 0;
}
/*
* aStruct.h
*/
#ifndef ASTRUCT_H_
#define ASTRUCT_H_
struct aStruct {
int value1;
int value2;
struct smallerStruct ssTest;
};
typedef struct aStruct aStruct;
aStruct createStruct();
#endif /* ASTRUCT_H_ */
/*
* smallerStruct.h
*/
#ifndef SMALLERSTRUCT_H_
#define SMALLERSTRUCT_H_
struct smallerStruct {
int value3;
};
typedef struct smallerStruct smallerStruct;
smallerStruct createSmallerStruct();
#endif /* SMALLERSTRUCT_H_ */
/*
* aStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
#include "aStruct.h"
aStruct createStruct() {
aStruct asOutput;
printf("This makes sure that this code depends on stdio.h, just to make sure I know where the inclusion directive should go (main.c or aStruct.c).\n");
asOutput.value1 = 5;
asOutput.value2 = 5;
asOutput.ssTest = createSmallerStruct();
return asOutput;
}
/*
* smallerStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
smallerStruct createSmallerStruct() {
smallerStruct ssOutput;
ssOutput.value3 = 41;
return ssOutput;
}
This generates the following error messages:
At aStruct.h:10
field 'ssTest' has incomplete type
At main.c:8
unused variable `asTest' (this one makes sense)
The base of inclusion is to make sure that your headers are included only once. This is usually performed with a sequence like this one:
/* header.h */
#ifndef header_h_
#define header_h_
/* Your code here ... */
#endif /* header_h_ */
The second point is to take care of possible name conflicts by handling manually pseudo namespaces with prefixes.
Then put in your headers only function declarations of public API. This may imply to add typedefs and enums. Avoid as much as possible to include constant and variable declarations: prefer accessor functions.
Another rule is to never include .c files, only .h. This is the very point of modularity: a given module dependant of another module needs only to know its interface, not its implementation.
A for your specific problem, aStruct.h uses struct smallerStruct but knows nothing about it, in particular its size for being able to allocate an aStruct variable. aStruct.h needs to include smallerStruct.h. Including smallerStruct.h before aStruct.h in main.c doesn't solve the issue when compiling aStruct.c.
The multiple definition problem is most likely coming from the way you're including the code. You are using #include "aStruct.c" as opposed to #include "aStruct.h". I suspect you are also compiling the .c files into your project in addition to the #include. This causes the compiler to become confused due to the multiple definitions of the same function.
If you change the #include to #include "aStruct.h" and make sure the three source files are compiled and linked together, the error should go away.
Such errors mean that function declaration (return type or parameter count/types) differs from other function declarations or function definition.
previous declaration message points you to the conflicting declaration.