I tried to implement template like functionality in C by use of macros, but for some reason it throws me the error "c:4:25: error: expected identifier or '(' before '{' token"
Here's the code
#include<stdio.h>
#include<stdlib.h>
#define test(name, type){\
typedef struct{\
type x;\
type y;\
}name;\
}
test(IntVec2, int);
int main(){
printf("Hello, World!");
}
One way to debug this type of situation is to take a look at the output of the preprocessor. For exampl, we feed the following through the cpp preprocessor:
#define test(name, type){\
typedef struct{\
type x;\
type y;\
}name;\
}
test(IntVec2, int);
(I have omitted some of the code)
The result of the cpp program, is something like:
# 0 "test.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "test.c"
{ typedef struct{ int x; int y; }IntVec2;};
Now it becomes immediately apparent that the first { and last } should not have been in the macro definition.
Thus:
#define test(name, type)\
typedef struct{\
type x;\
type y;\
}name;
test(IntVec2, int);
Now leads to:
# 0 "test.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "test.c"
typedef struct{ int x; int y; }IntVec2;;
Note that even now, the ; at the end is obsolete (but relatively harmless in this specific case. Be very careful when using ; within macro definitions.
Removing the brackets solves the problem as {typedef...} is not a valid declaration as stated by Mat in the comments.
Related
I am working on a C project which has same definition of C function in multiple places. I am trying to get the definition of C function using compilation errors like "error: conflicting types for foo_func()"; which also provides header file declaration as "bar_file.h:< line no >: note: previous declaration of foo_func() was here". I want to rely on compilation error instead of grep like commands because compiler knows for sure which function it is linking with, so I can be sure of the function definition which is being used.
I am able to locate the header file with deliberately applying compilation error. Is there a way to use the similar technique to find the definition of function I am using at compilation time?
Example: Let's find the header file which has the declaration of the function we are using. We can end up into the following compilation error by purposeful introduction of multiple definition with a known parameter mismatch.
$ gcc -Wall -Wextra -c exmpl_01.c -I./
exmpl_01.c:5: error: conflicting types for ‘call_func_other_file’
exmpl_01.h:1: note: previous declaration of ‘call_func_other_file’ was here
$ head -4 exmpl_01.c
#include <stdio.h>
#include "exmpl_01.h"
int call_func(void);
int call_func_other_file(char *);
$ cat exmpl_01.h
int call_func_other_file(void);
You can try deliberately addind a duplicate definition in a separate translation unit. Then link all object files together (compiled with debugging symbols enabled). The linker will tell you in what file and on what line the duplicate is defined.
Maybe you are looking for -E switch ?
// a.h
int a() {
return 1;
}
and then, we have
// main.c
#include "a.h"
int main() {
return a();
}
and, with -E you can get
> gcc -E main.c
# 1 "main.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 331 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.c" 2
# 1 "./a.h" 1
int a() {
return 1;
}
# 2 "main.c" 2
int main() {
return a();
}
now, let's say our source has another file
// b.h
float a() {
return 1.0;
}
and main.c is slightly different
#include "a.h"
#include "b.h"
int main() {
return a();
}
you will be able to see the last definition of function
gcc -c -E main.c
# 1 "main.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 331 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.c" 2
# 1 "./a.h" 1
int a() {
return 1;
}
# 2 "main.c" 2
# 1 "./b.h" 1
float a() {
return 1.0;
}
# 3 "main.c" 2
int main() {
return a();
}
But, I am not sure whether this is something you are looking for ;)
Hmm ... if you want to stop at certain point, maybe this one will help you:
#include "a.h"
#include "b.h"
int main() {
a();
#error Quit!
printfun("aaa");
}
and this way, compilation will fail a #error
> gcc -c -Wfatal-errors main.c
In file included from main.c:2:
./b.h:1:7: fatal error: conflicting types for 'a'
float a() {
^
./a.h:1:5: note: previous definition is here
int a() {
^
1 error generated.
Or, you can simply introduce some sort of fake type
#include "a.h"
struct fake_type {
int fake_component;
};
struct fake_type *a();
int main() {
a();
}
and enforce the error
> gcc -c -Wfatal-errors main.c
main.c:7:19: fatal error: conflicting types for 'a'
struct fake_type *a();
^
./a.h:1:5: note: previous definition is here
int a() {
^
1 error generated.
Let assume that I can not have a private typedef in my header file. So I need to do connection to type that is specified from the outside. In other words the type MY_INT should be determined by the interface.
So are these two approaches equal?
First approach:
In file.h
#define MY_INT int
In file.c
typedef MY_INT my_int;
my_int *a,b;
Second approach
In file.c
typedef int my_int;
my_int *a,b;
Do both declare two variables: a pointer to an int and an integer variable?
Do both declare two variables: a pointer to an int and an integer variable?
Short: yes.
Long:
Macro substitution is nothing else then plain text substitution. So when you #define MY_INT int, everything the preprocessor does when he finds a MY_INT is replacing it with int.
After the preprocessor processed file.c in your first approach it will look exactly the same as file.c in the second approach.
You can have a look at the preprocessors output with most compilers. E.g. for GCC the command would look like this gcc -E -o file.i file.c. file.i will then contain the preprocessors output so the actual file wich will be passed to the compiler.
This is what GCC produced for your first approach:
# 1 "file1.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "file1.c"
# 1 "file.h" 1
# 2 "file1.c" 2
typedef int my_int;
my_int *a, b;
and here is the second one
# 1 "file2.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "file2.c"
# 1 "file.h" 1
# 2 "file2.c" 2
typedef int my_int;
my_int *a, b;
The only thing that differes is the name of the files I used. The rest is exactly the same.
What is wrong? I would like the xconcat line to work.
#define concat(a,b) a ## b
#define xconcat(a,b) concat(a,b)
int main() {
xconcat(xconcat(boost::variant<,int), >) y;
boost::variant<int> x;
return 0;
}
g++ -E x.cpp
# 1 "x.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "x.cpp"
int main() {
x.cpp:5:1: error: pasting "<" and "int" does not give a valid preprocessing token
x.cpp:5:1: error: pasting "int" and ">" does not give a valid preprocessing token
boost::variant<int > y;
boost::variant<int> x;
return 0;
}
The token pasting operator technically can't be used to paste something that doesn't end up being a token. GCC enforces that restriction, while some other compilers don't (the ## operator just seems to perform basic concatenation of the strings which then gets tokenized later).
From C++11 16.3.3/3 "The ## operator":
If the result is not a valid preprocessing token, the behavior is undefined.
The same language is in pretty much every C and C++ standard going back to C90.
In your case you don't need to use token pasting since you're dealing with separate tokens anyway:
#define yyconcat(a,b) a b
#define yconcat(a,b) yyconcat(a,b)
int main() {
yconcat(yconcat(boost::variant<,int), >) y;
boost::variant<int> x;
return 0;
}
g++ -E so-test.c
C:\so-test>g++ -E so-test.c
# 1 "so-test.c"
# 1 "<command-line>"
# 1 "so-test.c"
int main() {
boost::variant< int > y;
boost::variant<int> x;
return 0;
}
Example =
#define a 100
#define b 200
main()
{
int c=a+b;
}
After preprocessing
Output-
#define a 100
main()
{
int c=a+200;
}
You could try refactoring the macros to allow external configuration, i.e.
/* config.h */
/* set defaults for a and b */
#ifndef a
#define a 100
#endif
#ifndef b
#define b 200
#endif
and
/* main.c */
#include "config.h"
int main(void)
{
int c = a + b;
}
Then you can set the macros externally when building, for instance like this:
$ gcc -E -Da=a main.c
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"
# 1 "config.h" 1
# 4 "main.c" 2
int main(void)
{
int c = a + 200;
}
$ gcc -E -Db=b main.c
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"
# 1 "config.h" 1
# 4 "main.c" 2
int main(void)
{
int c = 100 + b;
}
Now, of course you don't have to use a separate configuration header, but I'd recommend it from a maintenance perspective, it will make it easier to keep track of available configuration settings and their defaults.
#define a 100
#define b 200
main()
{
#undef b
int c=a+b;
}
No. What's your real goal?
If you want to do, it's better to make some script to do that.
If you don't want to preprocess a macro, just don't use it:
#define a 100
//#define b 200
int main()
{
int c = a + 200;
return 0;
}
The purpose of preprocessing is to process the preprocessing directives. I don't know of any way to keep a specific preprocessing directive, especially because the next step, compilation, doesn't know anything about these.
This is another reason why you should be careful when using macros -- when the name is found in the source, then it is substituted, no matter what:
#define a 100
main()
{
int a; // Compilation error happens here
....
}
Regarding Peter Miehle's answer, unifdef can be used to partially process #if and #ifdef directives, but it cannot be used to selectively expand macros. See http://dotat.at/prog/unifdef
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.