Why is #define throwing "error: expected declaration specifiers"? - c

I'm new so apologies if my formatting is a little off.
I'm writing a simple OpenMP program in order to get the hang of it, and I've been stopped completely dead in my tracks by a strange compilation error. My serial implementation compiles just fine (with gnu11), but my parallel compilation seems to fail for some reason I can't locate.
The entire code up to the point of failure is as follows (and the error I receive from make follows thereafter)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define N_THR 1
#define MIN_SIZE 3 //NOTE: min_size is inclusive here
#ifdef _OPENMP
#include <omp.h>
#undef N_THR
#define N_THR 4
#undef MIN_SIZE
#define MIN_SIZE N_THR
//omp_set_dynamic(false); //we need to explicitly disable dynamic teams to force 4 threads
omp_set_num_threads(N_THR);
#endif
gcc maze.c -o maze
gcc maze.c -fopenmp -o mazep
maze.c:11:16: error: expected declaration specifiers or ‘...’ before numeric constant
#define N_THR 4
^
maze.c:15:22: note: in expansion of macro ‘N_THR’
omp_set_num_threads(N_THR);
^~~~~
make: *** [Makefile:5: parallel] Error 1
Is there some deep C language syntax hint I'm missing or is it something a little more obvious?

It's because you are calling omp_set_num_threads() outside of a function.

I got this error in this file canCom2.h
in this line
#define INST_CANCOM2 (2U)
because I had an extra closing curly braces in this file
eeeprom.c
} /* extra curly braces*/
#if defined(USING_CAN2) && defined(INST_CANCOM2)
After removing the extra curly brace, the error vanished

Related

Use concatenation and stringizing in the same macro with GCC

Those macros are compiled without error with visual studio and codewarrior compilers. With gcc the error is shown in the comment
#define STRINGIFY(x) #x
#define MYINC(n) STRINGIFY(extensions/##n##/myinc.h)
#include "extensions/1/myinc.h" // OK (no surprise)
#include STRINGIFY(extensions/1/myinc.h) // OK
#include MYINC(1) // error: pasting "1" and "/" does not give a valid preprocessing token
Some idea?
Actually On my environment (WSL2 gcc9.3), the line
#include STRINGIFY(extensions/1/myinc.h)
event triger compiling error
test1.c:6:10: error: #include expects "FILENAME" or <FILENAME>
6 | #include STRINGIFY(extensions/1/myinc.h) // OK
| ^~~~~~~~~
test1.c:7:17: error: #include expects "FILENAME" or <FILENAME>
7 | #include MYINC(1)
From GCC document https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html I found this:
The argument of ‘#include’, whether delimited with quote marks or angle brackets, behaves like a string constant in that comments are not recognized, and macro names are not expanded. Thus, #include <x/*y> specifies inclusion of a system header file named x/*y.
And MSVC-170 document https://learn.microsoft.com/en-us/cpp/preprocessor/hash-include-directive-c-cpp?view=msvc-170 says:
You can organize constant and macro definitions into include files (also known as header files) and then use #include directives to add them to any source file.
So I guess the problem is some gcc won't expand macro. But if I define:
#define INCFILE "extensions/1/myinc.h"
#include INCFILE
GCC didn't report error. And If I write:
#define INCFILE "extensions/1/myinc.h"
#include STRINGIFY(INCFILE)
GCC also reports:
test1.c:5:10: error: #include expects "FILENAME" or <FILENAME>
5 | #include STRINGIFY(INCFILE) // OK

#include <windows.h> causes errors

I'm trying to use GetTickCount() from the windows.h header file. Right now my code looks like this:
#include <stdio.h>
#include <string.h>
#include "declarations.h"
#define INPUTBUFFER 400 * 6
#define START_POS "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
#include <windows.h>
void interface() {
.....
.....
}
The compiler returns 2 errors:
Expected '{' before '(' token (pointing to the '(' after "interface"
2 or more data types in declaration specifiers (pointing to "interface")
When I comment out #include < windows.h >, the interface function works just fine. I don't even have GetTickCount() in my code yet. I checked the gcc path to make sure windows.h is there, so I'm not sure why I'm getting this error.
As RbMm points out in a comment, the windows headers contain "#define interface struct", so the compiler sees your code as "void struct() { ....}" which is not valid C++
You need to either rename your function (probablly the better option) or add a "#undef interface" before your function.

An interesting thing about overriding linux kernel macro

In the following code, it is compiled success and print 1024
#include <stdio.h>
#define FD_SETSIZE 512
#include <sys/types.h>
int main()
{
printf("%d\n", FD_SETSIZE);
}
But in the following code, it is compiled failed and print
test.c:4:1: warning: "FD_SETSIZE" redefined
In file included from /usr/include/sys/types.h:220,
from test_fd.c:3:
/usr/include/sys/select.h:81:1: warning: this is the location of the previous definition
the code is
#include <stdio.h>
#include <sys/types.h>
#define FD_SETSIZE 512
int main()
{
printf("%d\n", FD_SETSIZE);
}
Can anbody explain this? Thanks!
But in the following code, it is compiled failed and print
In the question, both the programs were compiled, but while compiling first program you got warnings in preprocessor stage.
Preprocessor stage is responsible for the replacement of macros.
In this example the preprocessor is using the last defined macro and replacing it.
#include <stdio.h>
#define FD_SETSIZE 512
#include <sys/types.h>
Here the definition of FD_SETSIZE is there in both the .c file and also in header file sys/types.h.
After the file inclusion, then the replacing of macros will be done,so the latest defined macro is replaced.
So the final replacement FD_SETSIZE of will be same as defined in the sys/types.h file and vice-versa.
Hope this is helpful.
you can use the #undef directive to remove the defined macro and replace it later
#ifdef MACRO
#undef MACRO
#endif
#define MACRO

How can I create a string constant in gcc 4.9.2?

I'm running on Arch Linux with GCC 4.9.2, and I've been having trouble compiling the following code:
#ifndef WORLD_H
#define WORLD_H
#include <string.h>
#include <stdio.h>
//#include "removeBuffering.h"
//World dimensions
#define WORLD_WIDTH 80
#define WORLD_HEIGHT 20
//World block types
#define FLAT_LAND '-'
//Instructions
#define MOVE_UP 'w'
#define MOVE_DOWN 's'
#define MOVE_RIGHT 'd'
#define MOVE_LEFT 'a'
#ifndef WIN32
#define COMMAND "clear" //Clears a linux console screen
#else
#define COMMAND "cls" //Clears a windows console screen
#endif
#define wipe() system( COMMAND )
It works on my koding.com VM, which uses GCC 4.8.2 but on my local machine, it generates the following error:
include/world.h:17:17: error: expected declaration specifiers or ‘...’ before string constant
#define COMMAND "clear" //Clears a linux console screen
I'm thinking it's due to some sort of change in GCC 4.9, but I can't seem to find any good information about it, so any help would be greatly appreciated
Run this through gcc -E -- this will expand the results, at which point all should become clear.
Before I give my own answer, I want to give you an overview of how my code looked while it was generating the error message above. Here's world.h:
#ifndef WORLD_H
#define WORLD_H
#include <string.h>
#include <stdio.h>
//#include "removeBuffering.h"
//World dimensions
#define WORLD_WIDTH 80
#define WORLD_HEIGHT 20
//World block types
#define FLAT_LAND '-'
//Instructions
#define MOVE_UP 'w'
#define MOVE_DOWN 's'
#define MOVE_RIGHT 'd'
#define MOVE_LEFT 'a'
#ifndef WIN32
#define COMMAND "clear" //Clears a linux console screen
#else
#define COMMAND "cls" //Clears a windows console screen
#endif
int cursorXPos;
int cursorYPos;
char world[WORLD_HEIGHT][WORLD_WIDTH+1]; //Space for null terminator
void initializeWorld();
void printWorld();
void getInput();
//void printHelp();
#endif
Here's world.c (I've emptied the functions to save space)
#include "world.h"
void initializeWorld()
{
}
void printWorld()
{
}
void getInput()
{
}
system(COMMAND);
printWorld();
And here is the FULL error list provided by GCC:
In file included from src/world.c:1:0:
include/world.h:17:17: error: expected declaration specifiers or ‘...’ before string constant
#define COMMAND "clear" //Clears a linux console screen
^
src/world.c:78:10: note: in expansion of macro ‘COMMAND’
system(COMMAND);
^
src/world.c:79:3: warning: data definition has no type or storage class
printWorld();
^
src/world.c:79:3: error: conflicting types for ‘printWorld’
src/world.c:13:6: note: previous definition of ‘printWorld’ was here
void printWorld()
In my experience, it was always a good idea to deal with the very first error on the list, so I didn't pay much attention to anything besides the first error, which is why I asked the question in the first place. I eventually tried to resolve the later errors as Carey Gregory and immibis suggested.
The important ones were:
src/world.c:79:3: warning: data definition has no type or storage class
printWorld();
^
src/world.c:79:3: error: conflicting types for ‘printWorld’
src/world.c:13:6: note: previous definition of ‘printWorld’ was here
void printWorld()
As soon as I moved the misplaced function call for printWorld() (and system()), the errors disappeared.

Are #include directives processed prior to macro expansion regardless of their location within a file?

I came across some code the other day that was similar to the following (the following has been over-simplified for the sake of brevity):
config.h
#ifndef __CONFIG__
#define __CONFIG__
#define DEVELOPMENT_BLD _TRUE_
#if (DEVELOPMENT_BLD == _TRUE_)
#define FILE_EXT ".dev"
#else
#define FILE_EXT ".bin"
#endif
#define PROJECT_STRING "my_project"
#define FILE_NAME PROJECT_STRING FILE_EXT
/* Common include files */
#include "my_defs.h"
#endif /* __CONFIG__ */
my_defs.h
#ifndef __MY_DEFS__
#define __MY_DEFS__
#define _TRUE_ 1
#endif /* __MY_DEFS__ */
The project had always compiled without any issues, but since I made some minor changes (and the actual project was rather large) I decided to run Lint on it. When I did, I received the following error:
Warning 553: Undefined preprocessor variable '_TRUE_', assumed 0
I then wondered why the compiler didn't catch that _TRUE_ is defined in my_defs.h which is included after the macro's first usage. So I compiled it on a different compiler with the same results - succesful compilation, no warnings and FILE_NAME was correctly evaluated regardless of how I set DEVELOPMENT_BLD (using _TRUE_ or !_TRUE_). Here are my two compiler settings:
ArmCC -c -cpu Cortex-M3 -g -O0 --apcs=interwork -I "..\ARM\CMSIS\Include" -I "..\ARM\INC\NXP\LPC17xx" -o "file.o" --omf_browse "file.crf" --depend "file.d" "file.c"
mingw32-gcc.exe -pedantic -Wall -g -c D:\dev\practice\header_question\main.c -o obj\Debug\main.o
I decided to run a simple test to see if the value of FILE_NAME was being properly evaluated by the preprocessor. I also wanted to see what the value of DEVELOPMENT_BLD actually was. I ran the following code two times:
main.c
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("FILE_NAME:%s, WHAT_IS_TRUE:%d", FILE_NAME,DEVELOPMENT_BLD);
return 0;
}
The first time I used the value #define DEVELOPMENT_BLD _TRUE_ with this result:
FILE_NAME:my_project.dev, WHAT_IS_TRUE:1
The second time I used the value #define DEVELOPMENT_BLD !_TRUE_ with this result:
FILE_NAME:my_project.bin, WHAT_IS_TRUE:0
My first thought was that perhaps _TRUE_ was being defined elsewhere - so just to be sure I commented out #include "my_defs.h". I then began to receive a compiler error:
error: '_TRUE_' undeclared (first use in this function)
All of that leads to my question. Are #include statements required to be evaluated by the preprocessor before macro expansion or did I just get lucky?
The C pre-processor acts on directives as it encounters them. In this context, the warning is correct; at the time you use #if DEVELOPMENT_BUILD == _TRUE_, the effective value of _TRUE_ is zero. However, because of the #define DEVELOPMENT_BUILD _TRUE_ definition, the preprocessor is evaluating #if 0 == 0, which is true. However, you'd have had the same result if you'd specified #define DEVELOPMENT_BUILD _FALSE_ because _FALSE_ would also be implicitly 0 and hence the test would be #if 0 == 0 again (which also evaluates to true). If, when the preprocessor has finished evaluating expressions in the #if condition, there are identifiers left over, they are implicitly assumed to be 0.
Note that names starting with an underscore and a capital letter or another underscore are reserved for any use by the implementation. You are treading on very thin ice with your choice of names such as _TRUE_ and __CONFIG__. (Just because system headers use names like that is not a good reason for you to do so — in fact, quite the opposite. The system headers are carefully keeping out of the namespace reserved for you to use; you should keep out of the namespace reserved for the system.)

Resources