C - "Error: Expected identifier or '(' before '[' token" - c

I am making a rogue-like game in C and I am having trouble with file linkage.
I am making a custom header file where I declare an array of structures, but when I compile this code:
#ifndef spells
#define spells
struct spells SpellList[55];
#endif // spells
I get an error: Expected identifier or '(' before '[' token.

You are using the identifier spells for two different purposes: as a "guard macro" for the header file, and as the tag-name for a struct. The compiler does not understand that you want these to be independent. With the code as shown, the preprocessing stage will replace all uses of the identifier spells with nothing, and then the parsing stage will see
struct SpellList[55];
which is invalid.
You must rename either the guard macro or the struct tag. Since you never need to refer to guard macros anywhere else, it's probably easiest to rename the guard macro.
Incidentally, "rouge" is a type of make-up. The kind of game you are making is a rogue-like.

I think the problem is using your defined symbol spells as a type.
Where you have:
struct spells SpellList[55];
The preprocessor will replace spells in that line with the value of the spells define (nothing) before the compiler tries to compile the code. This produces invalid code.

Related

Does non-reserved identifier at translation phase 4 make it impossible to reserve a file scope identifier at translation phase 7?

Consider this code:
/*
* stdio.h
*
* note: it is an example of a particular implementation of stdio.h
* containing _x; it is not "my code added to stdio.h"
*/
void _x(void);
/* t627.c */
#define _x 0
#include <stdio.h>
Invocation:
$ gcc t627.c
t627.c:1:12: error: expected identifier or ‘(’ before numeric constant
1 | #define _x 0
| ^
stdio.h:1:6: note: in expansion of macro ‘_x’
1 | void _x(void);
At translation phase 4 the identifier _x is non-reserved. At translation phase 7 the identifier _x is reserved (for use as identifier with file scope in both the ordinary and tag name spaces). Since translation phase 4 precedes translation phase 7, then at translation phase 7 the identifier _x (currently defined as a macro name) is already replaced by its replacement list 0, invalidating the program.
Does it mean that in cases when the user-defined macro (that begins with an underscore, followed by a lowercase letter) can collide/overlap with the file scope identifier with the same name, such file scope identifier cannot be reserved?
#define macros are always a textual substitution.
Headers, of course, are not compiled entities in their own right, so are only evaluated at the point they are #included.
Let's say you have a header containing a certain non-macro identifier*.
In a C module, you #define that same identifier to expand to something arbitrary and pathological, and then #include the header
Since the compiler encounters the #define before it encounters the #include, all mentions in the header of the colliding identifier will be substituted with the macro's expansion. The consequences can be (and often are) disastrous, or at the very least hard to debug.
It doesn't really matter whether or not the identifier starts with an underscore. If you wrote #define printf scanf, just for instance, that would cause chaos!
(* I stipulate "non-macro" just to avoid the complications of what would happen if the header redefined - or tried to - the macro you defined first.)
You're not allowed to define macros with any of the reserved names. This is stated explicitly in section 7.1.3p2 of the C standard:
If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
(Boldface: my emphasis.)
To put it another way, every identifier that is reserved in some phase-7 context is also reserved for use as a macro name.
Found a relevant quote from P.J. Plauger (emphasis added):
Remember that the user can write macros that begin with an underscore, followed by a lowercase letter. These names overlap those reserved to the implementor for naming external functions and data objects.
So, the answer seems to be "yes".

What does #define without assignment assign to in C?

I have often seen code like
#ifndef HEADERFILE_H
#define HEADERFILE_H
// some declarations in
// the header file.
#endif
I want to know what #define HEADERFILE_H define HEADERFILE_H to?
I tried doing
cout<<HEADERFILE_H<<endl;
but I am getting
error: expected expression
A define preprocessing directive has the form # define identifier preprocessing-tokens, ending with a new-line character. The preprocessing-tokens is a list of zero or more preprocessing tokens. It may be empty, that is, it may have zero tokens. This means, that when the identifier is encountered in a place where macro replacement occurs, it will be replaced with nothing.1
Tests of the form #ifdef identifier, #ifndef identifier, or define identifier in a #if or #elif directive test whether identifier is defined or not. If it was not defined (or its definition was removed with the #undef directive), then the test indicates it is not defined. If it was defined, then the test indicates it was defined, even if the definition is for zero tokens.
A definition with zero tokens is different from no definition at all, and defined identifier will evaluate as true for the former and false for the latter.
Footnote
1 If the list does have tokens, then identifier will be replaced with those tokens and # and ## operators among them will be applied. A preprocessing token is largely an identifier (like foo34), a constant (like 3, 4u, or 1.8e4), one of the C operators or special characters (like * or +=), or certain other components of the C language.
It actually defines "nothing else than itself". That is: you may define a macro without assigning it a specific value. Since you can check if a given macro is defined or not, you therefore can ask for the simple "existence" of a given macro.
This is useful to indicate a context (for example, if you're compiling for a given OS) and/or the availability of some resources.
In this particular example, this is a called a "guard": it will define itself if this hasn't been done first before, as well as including the rest of the file, which is totally embedded in the #ifdef … #endif clause.
This is used to implement a kind of require_once, that is something that will be included if needed, but not multiple times. This is required when you are defining functions or declaring variables at a global scope, for instance.
This is a language idiom (I will comment it):
#ifndef HEADERFILE_H
Between this, and the last #endif everything is included in compilation, but only if HEADERFILE_H has not been defined before.
#define HEADERFILE_H
The first thing we do in the block is to #define the identifier, so next time we find this fragment again later, the contents between #ifndef and #endif will not be #included again (because of the identifier declaration).
// some declarations in
// the header file.
this block will be included only once, even if you #include this file several times.
#endif
and this marks the end of the protected block.
It is common to include some file that, indeed, #includes another, and that file includes another, leading to a point in which you don't know which files have been included and which don't. This phrasing allows you to be protected, and to be able to #include the same file several times (normally you cannot, as some definitions cannot be repeated in the same compilation unit, e.g. declarations) the lines above will include the contents and define the identifier, making next inclussions (that are effectively done) not to include the contents, as the identifier appears as #definen in second and ulterior times.

What preprocessor macros can't be defined?

I noticed that trying to define defined as a macro in C/C++ gives an error:
error: "defined" cannot be used as a macro name
This doesn't seem strange to me, since allowing the redefinition of defined would probably break #if defined(...)-like directives. However, It made me wonder what other keywords would give a compilation error1. I found that the C++ named operators also can't be used in a define, but I couldn't find a list of all impossible macros. Are there any other macros that cannot be defined?
1 while (re)defining keywords such as if, or int are about the worst thing one could do with the preprocessor, doing so does not cause a compilation error. I'm looking for keywords that won't compile at all.
Per gnu.org, "you may define any valid identifier as a macro, even if it is a C keyword. The preprocessor does not know anything about keywords. This can be useful if you wish to hide a keyword such as 'const' from an older compiler that does not understand it. However, the preprocessor operator 'defined' can never be defined as a macro."

C89 - error: expected ')' before '*' token

I am getting this error within C.
error: expected ')' before '*' token
But cannot trace it.
void print_struct(struct_alias *s) //error within this line
{
...
} //end of print method
My question is when receiving this error where can the error stem back to? Is it a problem with the function, can it be an error with what is being passed in? What is the scope of the error?
The compiler doesn't recognize the name struct_alias as a type name.
For that code to compile, struct_alias would have to be declared as a typedef, and that declaration would have to be visible to the compiler when it sees the definition of print_struct.
(Typedef names are tricky. In effect, they become temporarily user-defined keywords, which is why errors involving them can produce such confusing error messages.)
This is not specific to C89; it applies equally to C90 (which is exactly the same language as C89), to C99, and to C11.
The error means that here's no such type as struct_alias declared in this translation unit.

How to track down cause of missing struct from include files in C?

I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
When I run the preprocessor over this project, it does include that file, but the preprocessor output does not have the struct definition (but does include enum's from that file).
Is there a method to figure out why some of a header file gets to the preprocessor output, and some does not?
TIA
(Also, this is not the only compile error, the port is half done but it should be at least getting past this part)
I usually just track back from the structure to find all the enclosing "#ifdef" and "#if" lines that the preprocessor will encounter and see which one is controlling the removal of the structure from the input stream into the compiler.
That generally works pretty quickly for all but the hairiest of header files (i.e., those with a great many nested conditional compile statements). For those, I generally have a look at the preprocessor output to identify the last line in the header file that made it to the compiler input stream.
Almost certainly the next line will be a conditional compile statement where you haven't met the condition for inclusion.
For example, if this is the header file, you would need to track back to see that _KERNEL should be defined in order to get the declaration and definition.
I'm afraid not; you will have to look for #ifdefs that surround your area of interest and track down why those symbols are not defined. If it's porting to Linux/UNIX and you are missing things from the standard headers, you might have not defined the right _XOPEN_SOURCE or _BSD_SOURCE in your Makefile or config.h .
The most likely reason is there's a #define somewhere around the definition. Since the corresponding symbol is not defined or defined to some other value the definition is not included even when the header itself is included. You'll have to inspect this manually.
Raymond Chen has a blog post about this.
You may find yourself in a twisty maze of #ifdefs. Or you may be wondering why your macros aren't working.
I have these lines in my header file:
#define MM_BUSY 0x0001
#define MM_IDLE 0x0002
but when I try to use them, I get errors.
sample.cpp(23): error C2065: 'MM_BUSY': undeclared identifier
sample.cpp(40): error C2065: 'MM_IDLE': undeclared identifier
Any idea why this is happening?
Solution: Use #error to track down the problem the same way you'd scatter printf around to track down a regular bug.
Source: Use the #error directive to check whether the compiler even sees you
I do not think that there is a better way beside checking the preprocessor output to know why one file is included or not. Here is the gcc's preprocessor's output format that may help you understand the preprocessor's ouput.
Also, another way you may have a try to compare the outputs between that you are porting and the existing one.
You said:
I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (Prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
This error can occur if you try to embed a pmc_mdep into some other structure before you have defined a pmc_mdep fully. Note that you can embed pointers to incomplete types into structures, but not actual instances of the incomplete type.
You also discuss running the preprocessor over the file that should define the structure, and you see enums form the header, but not the structure definition. That suggests that maybe you have a stray comment that is removing the structure unintentionally, or perhaps you have the structure definition embedded between #ifdef XXX and #endif but XXX is not defined when you do the compilation. It could even be #if 0.
I'd run the C preprocessor on just the header that contains the structure definition to see what that produces; it will be shorter than trying to look at the output for the entire program (source file). If I couldn't spot the issue swiftly, I'd mark parts with something like stray enums to see which ones get through and which ones don't.

Resources