While trying to write a macro inside an enum, in C.
We have to sometimes write name of macro, above macro definition, why ?
#include <stdio.h>
enum month {
MSD //If I remove or comment this line, code does not work, why?
#define MSD 7
};
void main() {
printf("%d\n", MSD);
}
If we remove the 5th line of code, i.e. "MSD". We get error
empty enum is invalid. Why is this happening, can anyone explain, please ?
Macros and enums are separate things. Most importantly, a macro only exists at compile time so the preprocessor will replace all instances of MSD in the following code with 7 exactly as if you'd done a find-and-replace in your editor. Enums, on the other hand, exist at runtime and are generally numeric values mapped to symbols.
Now, with your code as you have it the MSD in your printf("%d\n", MSD); is replaced with 7 at compile time so the enum is never actually used. If you remove the 5th line of code the compiler sees an empty enum because the #define MSD 7 macro is filtered out by the preprocessor leaving nothing else inside the enum.
If intention is to define a enum. we can define as below.
(we can define MSD in form of enum of a #define, either one of this is required to use "MSD" in code for value 7)
#include <stdio.h>
enum month {
MSD = 7,
TST = 1 // added just for ref
};
// in linux requires int main() { <code> return 0;}
void main() {
printf("enum MSD == %d\n", MSD);
}
I was reading a source code of header file and wondered why have they written macros that way, in which I have posted
I think you may have misread a header file that was doing this slightly different thing:
enum thing_enum {
THING_ONE = 1,
#define THING_ONE THING_ONE
THING_TWO,
#define THING_TWO THING_TWO
// etc
};
This is the same as writing a normal enum declaration
enum thing_enum {
THING_ONE = 1,
THING_TWO,
// etc
};
and then, also, defining each enumerator as a macro that expands to itself:
#define THING_ONE THING_ONE
#define THING_TWO THING_TWO
// etc
Written this way, it should be clearer why you get an error when you comment out the ‘MSD’ line in your code: the #define doesn’t contribute anything to the definition of the enum, so you have an enum with no values, which the language does not allow.
Header files do this odd-looking thing because it makes each THING_ constant be both a macro and an enum value, which means you can use all the features of enum to set their values (e.g. in my example THING_TWO is equal to 2 without my having had to say so explicitly) and the names will be made visible to the debugger, but it’s still possible to check for the existence of a particular constant with #ifdef.
The disadvantages are that it doubles the length of the definition of the set of constants, you cannot make the type of each constant be anything other than int, and the constants cannot be used in an #if expression (except as the argument of defined).
(Note: A macro that expands to itself does not put the preprocessor into an infinite loop. THING_ONE is replaced with THING_ONE once and then the preprocessor moves on to the next token.)
MSD has nothing do with declaring above #define MSD 7, the reason for error is that enum{ }; should not be empty.
you get the below error if enum is empty.
main.c:12:1: error: empty enum is invalid
};
Try declaring another enum value there instead of MSD, it will work as shown below.
#defines are text replacements, they dont need any declarations, just definitions.
#include <stdio.h>
enum month {
x = 0
//MSD //If I remove or comment this variable declaration, code does not work, why?
#define MSD 7
};
void main() {
printf("%d\n", MSD);
}
Related
I am little bit confused. In our production environment, there are few macros already defined. These macros used to return some value. Now our requirement is to prepare some lookup based on these Macros' value. I have created char* array and defined some string at appropriate index. But my manger asked me to convert these macros to enum types and then do lookup. How to implement this using enum? What is the advantage of that? These macros are being used in many different files. Do I have to change anything if I defined enum type?
Thanks in advance !
Sample code:
#define macro_1 1
#define macro_2 2
#define macro_3 3
#define macro_4 4
Lookup:
const char* lookup[] = {.....};
How to implement this using enum?
I suppose your manager asked you to map the macros to enum type. You can simply define an enum type, as long the macros all have integer value, and the enum values don't use the same names as macros.
What is the advantage of that?
Macros are generally not encouraged as they are replaced by value before entering the compiler, it can be error prone compared to using enum types that are checked and managed by compiler.
These macros are being used in many different files. Do I have to change anything if I defined enum type?
Unfortunately yes. But if your macros are isolated in a centeral header file, you can work around by renaming the macros and naming the original names to enum value.
You may find this article useful. http://www.cs.utah.edu/~germain/PPS/Topics/C_Language/enumerated_types.html
Some codes
#include <stdio.h>
#define old_macro_1 1
#define old_macro_2 2
#define old_macro_3 3
enum MacroValues {
macro_1 = old_macro_1,
macro_2 = old_macro_2,
macro_3 = old_macro_3
};
void test_macros(void)
{
const char* lookup[] = {"M0", "M1", "M2", "M3"};
// use an enum variable directly
printf("enum MacrosValues %d\n", macro_1);
// define an enum variable to use as index
enum MacroValues m1 = macro_2;
printf("lookup[%d] = %s\n", m1, lookup[m1]);
}
int main(void)
{
test_macros();
return 0;
}
Preamble: I want to statically check amount of struct members in C program, so I created two macros, each of them creates constant int storing __LINE__ into variable:
#include <stdio.h>
#include <string.h>
#define BEGIN(log) const int __##log##_begin = __LINE__;
#define END(log) const int __##log##_end = __LINE__;
BEGIN(TEST);
struct TEST {
int t1;
int t2;
float t3;
int t4;
int t5;
int t6;
};
END(TEST)
main()
{
static_assert(__TEST_end - __TEST_begin == 6 + 3, "not_equal");
}
When I use C++ compiler with -std=c++11 option (c++ test.cpp -std=c++11), it works fine, but the same code (with replacement of static_assert to _Static_assert) doesn't work in C(gcc version 4.8.4) with a strange error as this expression could be evaluated at a compile time:
test.c: In function ‘main’: test.c:18:17: error: expression in static
assertion is not constant _Static_assert(__TEST_end - __TEST_begin
== 6 + 4, "not_equal");
How can I fix this error or achieve the original goal in C?
In C a variable even if defined with const is not a constant expression. _Static_assert requires its first parameter to be a constant expression. Therefore the same thing that can be done in C++ cannot be done in C.
You can do a runtime check instead; use assert.
Note that this method won't guard you against a programmer typing out two members in the same line or using multiple single line declarations of the same type, or adding an empty line (or a comment). Instead of forcing a programmer to follow a string coding pattern, just so that this assert will catch the error, it is less error prone to simply require the programmer to define a correct number of members. It is strictly better, because you can make the an undetectable error either way, but at least doesn't have to worry about the strict coding pattern.
A solution for your issue would be to use an anonymous enumeration. Instead of:
#define BEGIN(log) const int __##log##_begin = __LINE__
#define END(log) const int __##log##_end = __LINE__
Do:
#define BEGIN(log) enum { __##log##_begin = __LINE__ }
#define END(log) enum { __##log##_end = __LINE__ }
This is allowed in C11 since, unlike a const int (or even static const int) variable, an enumeration constant is defined to be an integral constant expression.
(As an aside, I omitted the terminal semicolon from my version of your BEGIN()/END() macros. In my opinion, declaration macros should not include a terminal semicolon, that should be provided by the macro user, so the macro behaves more like a non-macro C declaration.)
After reading through some of K&R's The C Programming Language I came across the #define symbolic constants. I decided to define...
#define INTEGER_EXAMPLE 2
#define CHAR_EXAMPLE 2
...so my question is how does C know if I'm defining an int or a char type?
#define-d names have no types. They just define textual replacements.
What the compiler is seeing is the preprocessed form. If using GCC, try gcc -C -E somesource.c and have a look at the (preprocessed) output.
In the 1980s the preprocessor was a separate program.
Read about the cpp preprocessor, and preprocessor and C preprocessor wikipages.
You could even define ill-defined names like
#define BAD #*?$ some crap $?
And even more scary you can define things which are syntactically incomplete like
#define BADTASTE 2 +
and later code BADTASTE 3
Actually, you want to use parenthesis when defining macros. If you have
#define BADPROD(x,y) x*y
then BADPROD(2+3,4+5) is expanded to 2+3*4+5 which the compiler understands like 2+ (3*4) +5; you really want
#define BETTERPROD(x,y) ((x)*(y))
So that BETTERPROD(2+3,4+5) is expanded to ((2+3)*(4+5))
Avoid side-effects in macro arguments, e.g. BETTERPROD(j++,j--)
In general, use macros with care and have them stay simple.
Regarding these defines, it doesn't, the expanded macros doesn't have a type. The pre-processor which processes the #define is just replacing text within the source code
When you use these defines somewhere, e.g.
int i = INTEGER_EXAMPLE;
This will expand to
int i = 2;
Here the literal 2 (which in this context is an int) is assigned to an int.
You could also do:
char c = INTEGER_EXAMPLE;
Here too, the literal 2 is an int, and it is assigned to a char. 2 is within the limits of a char though, so all is ok.
You could even do:
int INTEGER_EXAMPLE = 2;
This would expand to
int 2 = 2;
Which isn't valid C.
#define STRING VALUE
is just an instruction for the pre-processor to replace the STRING with VALUE
afterwards the compiler will take control and will check the types
It doesn't, this is the preprocessor. The type of the constant is dependent on the context in which it is used. For instance:
#define INT_EXAMPLE 257
char foo = INT_EXAMPLE;
will attempt to assign 257 in a char context which should generate a warning unless char has more than 8 bits on your computer.
#Defines are nothing but literal replacements of values. You might want to use
static const
As it respects scope and is type-safe. Try this:
#define main no_main
int main() // gets replaced as no_main by preprocessor
{
return 0;
}
Should give you linking errors. Or you could try and fool your teacher by this
#define I_Have_No_Main_Function main //--> Put this in header file 1.h
#include"1.h"
int I_Have_No_Main_Function()
{
return 0;
}
It doesn't. The #define statements are processed before the compiler starts its work. Basically the pre-processor does a search and replace for what you wrote and replaces it, for instance, all instances of INTEGER_EXAMPLE are replaced with the string 2.
It is up to the compiler to decide the type of that 2 based on where it's used:
int x = INTEGER_EXAMPLE; // 2 is an integer
char y = INTEGER_EXAMPLE; // 2 is a char
Preprocessor cannot know the type of the macro definition. Preprocessor will just replace all occurrence of 'CHAR_EXAMPLE' with '2'. I would use cast:
#define CHAR_EXAMPLE ((char)2)
I was writing some test code in C. By mistake I had inserted a ; after a #define, which gave me errors. Why is a semicolon not required for #defines?
More specifically :
Method 1: works
const int MAX_STRING = 256;
int main(void) {
char buffer[MAX_STRING];
}
Method 2: Does not work - compilation error.
#define MAX_STRING 256;
int main(void) {
char buffer[MAX_STRING];
}
What is the reason of the different behavior of those codes? Are those both MAX_STRINGs not constants?
#define MAX_STRING 256;
means:
whenever you find MAX_STRING when preprocessing, replace it with 256;. In your case it'll make method 2:
#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING 256;
int main(void) {
char buffer [256;];
}
which isn't valid syntax. Replace
#define MAX_STRING 256;
with
#define MAX_STRING 256
The difference between your two codes is that in first method you declare a constant equal to 256 but in the second code you define MAX_STRING to stand for 256; in your source file.
The #define directive is used to define values or macros that are used by the preprocessor to manipulate the program source code before it is compiled. Because preprocessor definitions are substituted before the compiler acts on the source code, any errors that are introduced by #define are difficult to trace.
The syntax is:
#define CONST_NAME VALUE
if there is a ; at the end, it's considered as a part of VALUE.
to understand how exactly #defines work, try defining:
#define FOREVER for(;;)
...
FOREVER {
/perform something forever.
}
Interesting remark by John Hascall:
Most compilers will give you a way to see the output after the preprocessor phase, this can aid with debugging issues like this.
In gcc it can be done with flag -E.
#define is a preprocessor directive, not a statement or declaration as defined by the C grammar (both of those are required to end with a semicolon). The rules for the syntax of each one are different.
define is a preprocessor directive, and is a simple replacement, it is not a declaration.
BTW, as a replacement it may contain some ; as part of it:
// Ugly as hell, but valid
#define END_STATEMENT ;
int a = 1 END_STATEMENT // preprocessed to -> int a = 1;
Both constants? No.
The first method does not produce a constant in C language. Const-qualified variables do not qualify as constants in C. Your first method works only because past-C99 C compilers support variable-length arrays (VLA). Your buffer is a VLA in the first case specifically because MAX_STRING is not a constant. Try declaring the same array in file scope and you'll get an error, since VLAs are not allowed in file scope.
The second method can be used to assign names to constant values in C, but you have to do it properly. The ; in macro definition should not be there. Macros work through textual substitution and you don't want to substitute that extra ; into your array declaration. The proper way to define that macro would be
#define MAX_STRING 256
In C language, when it comes to defining proper named constants, you are basically limited to macros and enums. Don't try to use const "constants", unless you really know that it will work for your purposes.
Because that is how the syntax was decided for the precompiler directives.
Only statements end with a ; in c/c++, #define is a pre-processor directive and not a statement.
The second version does not define a constant as far as the language is concerned, just a substitution rule for a block of text. Once the preprocessor has done it's job, the compiler sees
char buffer [256;];
which is not syntactically valid.
The moral of the story: prefer the const int MAX_STRING = 256; way as that helps you, the compiler, and the debugger.
This preprocessor directive:
#define MAX_STRING 256;
tells the preprocessor to replace all MAX_STRINGs with 256; - and with the semicolon. Preprocessor statements don't need a semicolon at the end. If you put one, the preprocessor actually thinks you mean it with a semicolon.
If you are confused with #defines for constants, const int would probably be easier to comprehend.
If you want to learn more on how to properly use these preprocessor directives, try looking at this website.
I have some legacy code that contains this typedef:
typedef enum simple_op_enum {
#define SOP(OPCODE, NAME, FORM, SUIFOP) OPCODE ,
#include "simple_ops.def"
LAST_OP
} simple_op;
The #include file contains several lines of the form:
/* no operand instructions */
SOP( NOP_OP, "nop ", BASE_FORM, io_nop)
The token "simple_op" occurs later in a struct:
typedef struct simple_instr_struct {
simple_op opcode; /* the opcode */
There are several things I don't understand:
What is accomplished by having a comma at the end of the #define statement? I thought that was illegal.
What is being accomplished by the enum, especially LAST_OP
How do I access the value of opcode in a simple_instr_struct?
It's not illegal, it's part of what the preprocessor will replace all instances of SOP(x, y, z) with.
It's creating an enumeration with the contents in simple_ops.def. Because the contents of that file are SOP(w, x, y, z) they will all turn into w, and the enum will be:
typedef enum simple_op_enum {
NOP_OP , // <- notice the space before the comma, like the #define does
... // the others
LAST_OP
} simple_op;
It also makes LAST_OP the last enumeration value. This is probably so the code can use LAST_OP to determine how many enum values there are (or the highest enum value, or something like that).
This #include thing is a clever trick so that the definitions can be all in the same place (the file) and the code that #includes it just defines SOP to be whatever it needs it to be. Then modifying that one file will affect the entirety of the code that needs it and the code uses them in whatever way it needs. For instance, some code might only need the name, so it would define SOP as #define SOP(w, x, y, z) x to extract the name.
3) You can access it by doing simple_instr_struct_instance.opcode
If in doubt about macros, you can always use the preprocessor to see how they expand:
gcc -E file.c -o file.txt
The output will be large if there are many header files included, but you will find your macros in there somewhere - probably towards the end
Comma at end of #define is legal. it's part of the macro. constants of enums are separates by comma, and this macro worries to that.
enum is just a var that can contain any of the values you specify in the enum declaration. since them are translated to numbers, LAST_OP will be equal to the number of possibilities.
you can access the member like:
struct simple_instr_struct a;
a.opcode=LAST_OP;
The comma is just part of the text replacement that will occur when the macro is used. In this case, it's to add a comma after each opcode, so that the list will make valid enum syntax.
The result of the #define and #include is an enumeration that looks like:
typedef enum simple_op_enum {
NOP_OP,
.
.
.
LAST_OP
} simple_op;
You can see the same by looking at the output of running your source code through the C preprocessor. LAST_OP is just the last entry in your new enumeration.
You'll need to define a variable of that type:
struct simple_instr_struct myStruct;
and then access the field you care about:
myStruct.opcode
it will extract out the opcodes as enums
enums need comma seperating, so its taking the OPCODE and putting a , after it which effectively generates
typedef enum simple_op_enum {
NOP_OP, BLAH , WHATEVER , ANOTHER ,
LAST_OP
} simple_op;
The point of the enum is to have an enum of all the opcodes available.
LAST_OP is useful for knowing things like how many opcodes you end up with, and also means there is no dangling comma for the last thing in the enum list.
if you have a instance of the struct , 'blah', then you get it by going blah.opcode = NOP_OP;