Macro undeclared, but defined in header - c

I'm facing a very weird problem.
This is map.h:
#define MAP_WIDTH 256
#define MAP_HEIGHT 256
typedef struct {
char exit_n;
char exit_s;
char exit_w;
char exit_e;
} room;
room map[MAP_WIDTH][MAP_HEIGHT];
void generate_map();
And this map.c:
#include "map.h"
void generate_map()
{
char room_x, room_y;
room_x = MAX_WIDTH/2;
room_y = MAX_HEIGHT/2;
// first room
map[room_x][room_y].exit_n = 1;
}
So, nothing really exotic. The problem is the compiler complaining about the two defined constants MAX_WIDTH and MAX_HEIGHT:
map.c: In function ‘generate_map’:
map.c:18: error: ‘MAX_WIDTH’ undeclared (first use in this function)
map.c:18: error: (Each undeclared identifier is reported only once
map.c:18: error: for each function it appears in.)
map.c:19: error: ‘MAX_HEIGHT’ undeclared (first use in this function)
What am I doing wrong?

It looks like you are using MAX_WIDTH (with an X) and MAP_WIDTH (with a P) in the two cases, same for the _HEIGHT constants.

In your header you say #define MAP_HEIGHT and in map.c you are trying to use MAX_HEIGHT. They are not the same.

All C compilers I know have a flag to stop after the preprocessing stage. This is pretty useful for solving preprocessor related problems. For example, gcc has the -E flag:
$ gcc -E map.c
# 1 "map.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "map.c"
# 1 "map.h" 1
typedef struct {
char exit_n;
char exit_s;
char exit_w;
char exit_e;
} room;
room map[256][256];
void generate_map();
# 2 "map.c" 2
void generate_map()
{
char room_x, room_y;
room_x = MAX_WIDTH/2;
room_y = MAX_HEIGHT/2;
map[room_x][room_y].exit_n = 1;
}
Hopefully this would have provided enough clues to spot the mistake.

Related

How to define constants in headers to use in multiple C files

When writing C code, I might want to define a constant array in a header file so that it may be used in multiple .c files.
Take the following example:
main.c
#include <stdio.h>
#include "main.h"
int main() {
int localmat[9];
for (int i = 0; i < 9; i++) {
localmat[i] = HEADERMAT[i];
}
matadd(localmat, HEADERMAT);
return 0;
}
main.h
#ifndef _MAIN_H_
#define _MAIN_H_
// Constant array
const int HEADERMAT[9] = {0,1,2,3,4,5,6,7,8};
// prototype function:
void matadd(int matA[9], const int matB[9]);
#endif
functions.c
#include "main.h"
void matadd(int matA[9], const int matB[9]){
for (int i = 0; i < 9; i++) {
matA[i] += matB[i];
}
}
The constant array HEADERMAT declared in main.h is used in both
main.c and functions.h. The header does use ifndef to prevent redefinitions and yet, the compiler will still complain about it being defined multiple times:
/usr/bin/ld: /tmp/ccVWhI0u.o:(.rodata+0x0): multiple definition of `HEADERMAT'; /tmp/ccRAIQ5u.o:(.rodata+0x0): first defined here
collect2: error: ld returned 1 exit status
What would be the better way of making this array accessible to both C files?
Header files are for declarations. So, this is one way:
// main.h
#ifndef _MAIN_H_
#define _MAIN_H_
// Constant array
const int HEADERMAT[9]; // <---- declaration only
// prototype function:
void matadd(int matA[9], const int matB[9]);
#endif
Then, in some source file (preferably main.c, since we declared in main.h)
// main.c
#include <stdio.h>
#include "main.h"
const int HEADERMAT[9] = {0,1,2,3,4,5,6,7,8}; // <---- definition here
int main() {
int localmat[9];
for (int i = 0; i < 9; i++) {
localmat[i] = HEADERMAT[i];
}
matadd(localmat, HEADERMAT);
return 0;
}
If you did it this way in the header file instead:
// main.h
// main.h
#ifndef _MAIN_H_
#define _MAIN_H_
// Constant array
static const int HEADERMAT[9] = {0,1,2,3,4,5,6,7,8}; // <-- static definition
// prototype function:
void matadd(int matA[9], const int matB[9]);
#endif
Then the array would be duplicated in every source file that included main.h, which, as the Jonathan Leffler's comments point out, is not that big of a deal (36 bytes). But for an array of appreciable size, the waste would be a concern.
If I understand you simply want to make the HEADERMAT[] array available in multiple source files, you can simply declare it as usual in any of the source files and then declare it as extern in any other source file that needs it.
To do so, you need to
define a macro for the array size in a common header so all sources will know the size of the array, e.g. #define HEADERMATSZ 9,
declare the array as usual in one of the C source files, e.g. const int HEADERMAT[HEADERMATSZ] = {0,1,2,3,4,5,6,7,8};,
in any other C source files that need access, declare extern const int HEADERMAT[HEADERMATSZ];.
Now you can simply use HEADERMAT[] as needed in any file where it is either declared originally, or as extern.
A short example, first the common header to be included by main.c and source1.c that holds a function that will use the array declared as extern, e.g.
#ifndef COMMONHDR
#define COMMONHDR 1
#define HEADERMATSZ 9 /* defined size of extern array */
void showoutput (void); /* declaration of function using extern array*/
#endif
For your main.c we will declare the array there, including the common header to provide the declaration for the function we will call from source1.c that uses the array declared extern, e.g.
#include <stdio.h>
#include "commonhdr.h"
const int HEADERMAT[HEADERMATSZ] = {0,1,2,3,4,5,6,7,8};
int main (void) {
puts ("output from other file");
showoutput();
}
(the showoutput() function being the function called from source1.c, also note HEADERMATSZ can be omitted if your initializer has the correct number of values -- including it ensures the array is sized correctly)
Finally the source1.c file we provide the function definition that uses the array extern,
#include <stdio.h>
#include "commonhdr.h"
extern const int HEADERMAT[HEADERMATSZ];
/* definition of function using extern array */
void showoutput (void)
{
for (int i = 0; i < HEADERMATSZ; i++) {
printf (" %d %d\n", i, HEADERMAT[i]);
}
}
Compile both sources into the final executable, e.g. with gcc,
gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast source1.c -o main main.c
Example Use/Output
$ ./main
output from other file
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
This method works well regardless whether it is on your PC or programming a micro-controller. By using extern, the array need not be const and can be modified in either source if it is mutable.

cannot malloc nfq_q_handle because of 'incomplete application error' [duplicate]

I have a struct where I put all the information about the players. That's my struct:
struct player{
int startingCapital;
int currentCapital;
int startingPosition;
int currentPosition;
int activePlayer;
int canPlay;
};
And that's my main:
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(int argc, char *argv[])
{ int s,i,numOfPlayers;
struct player *players;
printf("Give the number of players: \n");
scanf("%d",&numOfPlayers);
players = (struct player *)calloc(numOfPlayers,sizeof(struct player));
system("PAUSE");
return 0;
}
I'm asking the user to give the number of players and then I try to allocate the needed memory. But I'm getting this compiler error that I can't figure out:
invalid application of `sizeof' to incomplete type `player'
It means the file containing main doesn't have access to the player structure definition (i.e. doesn't know what it looks like).
Try including it in header.h or make a constructor-like function that allocates it if it's to be an opaque object.
EDIT
If your goal is to hide the implementation of the structure, do this in a C file that has access to the struct:
struct player *
init_player(...)
{
struct player *p = calloc(1, sizeof *p);
/* ... */
return p;
}
However if the implementation shouldn't be hidden - i.e. main should legally say p->canPlay = 1 it would be better to put the definition of the structure in header.h.
The cause of errors such as "Invalid application of sizeof to incomplete type with a struct ... " is always lack of an include statement. Try to find the right library to include.
Your error is also shown when trying to access the sizeof() of an non-initialized extern array:
extern int a[];
sizeof(a);
>> error: invalid application of 'sizeof' to incomplete type 'int[]'
Note that you would get an array size missing error without the extern keyword.
I think that the problem is that you put #ifdef instead of #ifndef at the top of your header.h file.
I am a beginner and may not clear syntax.
To refer above information, I still not clear.
/*
* main.c
*
* Created on: 15 Nov 2019
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "dummy.h"
char arrA[] = {
0x41,
0x43,
0x45,
0x47,
0x00,
};
#define sizeA sizeof(arrA)
int main(void){
printf("\r\n%s",arrA);
printf("\r\nsize of = %d", sizeof(arrA));
printf("\r\nsize of = %d", sizeA);
printf("\r\n%s",arrB);
//printf("\r\nsize of = %d", sizeof(arrB));
printf("\r\nsize of = %d", sizeB);
while(1);
return 0;
};
/*
* dummy.c
*
* Created on: 29 Nov 2019
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "dummy.h"
char arrB[] = {
0x42,
0x44,
0x45,
0x48,
0x00,
};
/*
* dummy.h
*
* Created on: 29 Nov 2019
*/
#ifndef DUMMY_H_
#define DUMMY_H_
extern char arrB[];
#define sizeB sizeof(arrB)
#endif /* DUMMY_H_ */
15:16:56 **** Incremental Build of configuration Debug for project T3 ****
Info: Internal Builder is used for build
gcc -O0 -g3 -Wall -c -fmessage-length=0 -o main.o "..\\main.c"
In file included from ..\main.c:12:
..\main.c: In function 'main':
..\dummy.h:13:21: **error: invalid application of 'sizeof' to incomplete type 'char[]'**
#define sizeB sizeof(arrB)
^
..\main.c:32:29: note: in expansion of macro 'sizeB'
printf("\r\nsize of = %d", sizeB);
^~~~~
15:16:57 Build Failed. 1 errors, 0 warnings. (took 384ms)
Both "arrA" & "arrB" can be accessed (print it out). However, can't get a size of "arrB".
What is a problem there?
Is 'char[]' incomplete type? or
'sizeof' does not accept the extern variable/ label?
In my program, "arrA" & "arrB" are constant lists and fixed before to compile. I would like to use a label(let me easy to maintenance & save RAM memory).
Really late to the party here, but a special case of the reasons for this error cited above would simply be to reference a structure with sizeof() above where the structure is defined:
int numElements = sizeof(myArray)/sizeof(myArray[0]);
.
.
.
myArray[] =
{
{Element1},
{Element2},
{Element3}
};

expected ')' before '*' token, can't seem to find error

So whenever I try to run my Makefile on my server, it always gives me the error is "Memory.c: 9 error: expected ')' before '*' token. But when I try to run it on my own computer, it works just fine. I've been trying to figure out what is wrong but can't seem to find it.
I've attached the 3 files that are used in this part of my program. Memory.c, Memory.h and ProcessInput.h.
This is Memory.c
/* Initializes memory */
#include <stdio.h>
#include <stdlib.h>
#include "memory.h"
void initializeMemory(memory** memArray, int memSize)
{
// Allocating space for memory array
*memArray = malloc(memSize * sizeof(memory));
if(*memArray == NULL)
{
fprintf(stderr, "Error allocating space for array of memory" );
exit(1); // exit(1) = Unsuccessful exit
}
// Initializing the contents within memory array
int i = 0;
for(i = 0; i < memSize; i ++)
{
((*memArray)[i]).occupied = false;
}
}
and this is Memory.h
// Definitions for Memory.c
#define bool int
#define true 1
#define false 0
#include "ProcessInput.h"
// Include guards to prevent redefinition of struct
#ifndef MEMORY_H
#define MEMORY_H
typedef struct memoryDetail
{
process process;
bool occupied;
} memory;
#endif
// Function declaration for memory.c
void initializeMemory(memory** memArray, int memSize);
the only thing used from ProcessInput.h is the process structure defined in ProcessInput.h
This is ProcessInput.h
// Include guards to prevent redefinition of struct
#ifndef PROCESSDETAIL_H
#define PROCESSDETAIL_H
typedef struct processDetail
{
int timeCreated;
int processID;
int memorySize;
int jobTime;
} process;
#endif
// function declarations for ProcessInput.c
void processInput(int* maxSize, int* count, process** processes, char* fileName);
I'm not too sure why it's giving me the error. I don't know where I'm supposed to be putting a missing right brace. Any advice is much appreciated!
edit: As informed, these are the following questions that I looked at but to not avail.
error: expected ‘)’ before ‘*’ token
Multiple of same error while compiling "error: expected ')' before '*' token
http://www.dreamincode.net/forums/topic/288956-error-expected-before-token/
thanks everyone for the help!
#include "memory.h" is different to #include "Memory.h" (i.e. C is case sensitive)
If you tried #include "myfile.h" instead of #include "MyFile.h" the error may be more obvious. In this case it just happens that the compiler finds the system memory.h.
<memory.h> is a header from C library of pre-standard era. It is quite possible that your standard library still provides it and the compiler takes that one instead of yours.
Try renaming your header file and see if it changes anything.

"error: expected specifier-qualifier-list before XXX"?

I'm trying to "implement" a cross-platform mutex following the instructions here:
And here is my code:
#ifndef __SIMPLEAV_CORE_UTIL_SAMUTEX_H_DEFINED__
#define __SIMPLEAV_CORE_UTIL_SAMUTEX_H_DEFINED__
/*
* A simple cross-platform (currently only on linux and win) mutex.
*
* usage:
* SAMutex mutex;
* SAMutex_init(&mutex);
* SAMutex_lock(&mutex);
* SAMutex_unlock(&mutex);
* SAMutex_destroy(&mutex);
*
* all functions return 0 on success, -1 on error.
*/
#if defined(LINUX)
#include <pthread.h>
//typedef pthread_mutex_t SAMutex;
#define SAMutex pthread_mutex_t
#elif defined(WINDOWS)
#include <windows.h>
#include <process.h>
//typedef HANDLE SAMutex;
#define SAMutex HANDLE
#endif
int SAMutex_init(SAMutex *);
int SAMutex_lock(SAMutex *);
int SAMutex_unlock(SAMutex *);
int SAMutex_destroy(SAMutex *);
#endif
but what I got after running gcc was:
~/git/SimpleAV/build $ make
[ 20%] Building C object CMakeFiles/player2.dir/player2.c.o
In file included from /home/wecing/git/SimpleAV/include/SimpleAV/core/core.h:4,
from /home/wecing/git/SimpleAV/include/SimpleAV/SDL/api.h:5,
from /home/wecing/git/SimpleAV/player2.c:4:
/home/wecing/git/SimpleAV/include/SimpleAV/core/util/SAMutex.h:28: error: expected ‘)’ before ‘*’ token
/home/wecing/git/SimpleAV/include/SimpleAV/core/util/SAMutex.h:29: error: expected ‘)’ before ‘*’ token
/home/wecing/git/SimpleAV/include/SimpleAV/core/util/SAMutex.h:30: error: expected ‘)’ before ‘*’ token
/home/wecing/git/SimpleAV/include/SimpleAV/core/util/SAMutex.h:31: error: expected ‘)’ before ‘*’ token
In file included from /home/wecing/git/SimpleAV/include/SimpleAV/SDL/api.h:5,
from /home/wecing/git/SimpleAV/player2.c:4:
/home/wecing/git/SimpleAV/include/SimpleAV/core/core.h:28: error: expected specifier-qualifier-list before ‘SAMutex’
make[2]: *** [CMakeFiles/player2.dir/player2.c.o] Error 1
make[1]: *** [CMakeFiles/player2.dir/all] Error 2
make: *** [all] Error 2
by the way, on linux, pthread_mutex_t is defined as:
typedef union
{
struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
int __owner;
#if __WORDSIZE == 64
unsigned int __nusers;
#endif
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
#if __WORDSIZE == 64
int __spins;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
#else
unsigned int __nusers;
__extension__ union
{
int __spins;
__pthread_slist_t __list;
};
#endif
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
} pthread_mutex_t;
What did I do wrong?
have you defined LINUX or WINDOWS define in your Makefile?
try
gcc -dM -E - < /dev/null
this prints all the predefined macros.
and here the windows macros.
It looks that gcc doesn't see the macro definition in the #ifdef. I think __linux__ is the correct macro to test. Or even better test for the macros from POSIX and not for Linux alone.
Edit: Probably the best is test for _XOPEN_SOURCE. POSIX imposes that this is defined before any header is included.

#define f(g,g2) g##g2

#define f(g,g2) g##g2
main()
{
int var12=100;
printf("%d",f(var,12));
}
The above program prints 100 in c by concatenating var and 12. How does g##g2 work??
## just pastes tokens together. It is a preprocessor directive.
E.g.
#define PASTE(a,b) a##b
int i=PASTE(1,2); /* int i=12; */
## is the preprocessor "command" for concatenating what comes before and after.
This is token pasting, described here for gcc. Token pasting is done by the preprocessor, not the compiler.
So after preprocess it will look like this:
main()
{
int var12=100;
printf("%d",var12);
}
Concatenation is being performed by the preprocessor because you used the ## command.
When you are unsure what the preprocessor is doing you can ask gcc to stop after it has run the preprocessor. Since this is before the compiler runs, the output is fairly easy to understand.
For example, assume you have a file pre.c
#define FOO 123
#define CONCAT(x,y) x##y
#define STRING(x) #x
void main()
{
int a = FOO;
int b = CONCAT(123,4567);
char* c = STRING(IGetQuoted);
}
You can produce the preprocessor output by passing the -E option to gcc.
$ gcc -E pre.c
# 1 "pre.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "pre.c"
void main()
{
int a = 123;
int b = 1234567;
char* c = "IGetQuoted";
}
Keep in mind that #include will pull in the contents of the file it specifies and can make the preprocessor output rather long.

Resources