This is my first post, so if I'm being too vague or giving information that everyone would intuitively assume, please let me know.
I'm very new to writing in C and am just trying to get a better understanding of preprocessing. I'm writing a simple program that can take in arguments either directly from the console using gcc -Wall -std=c99 -DSEED=argument, where my argument should be a an integer, or if the -D is not defined the user will input it.
The SEED value is simply used in srand(). I'm very confused why my code will not compile if I put in an -DSEED=a as my argument while if I put -DSEED=1 it will compile. I'm getting a "âaâ undeclared (first use in this function)" error and really don't understand the difference between the two. I thought the #define matched up the variable type with the input, so if I put in an "a" #SEED would be a char and if I put in a "1" #SEED would be an int.
If the SEED is not defined I'm using a #ifndef SEED command and this works well.
I think I'm supposed to "stringify" the input SEED and then can check if it is an integer or not. After reading some articles online I'm trying to use:
#ifndef SEED
//code
#else
#define TO_STRING( input ) #input
char c;
c = TO_STRING( SEED )
//Then I was going to use c to figure out if it was an int.
#endif
This is not working and anyone able to point out any misconceptions that you think that I may have would be greatly appreciated.
EDIT - So I did figure out why I was receiving the error message when trying the -DSEED=a, because it was reading it as a variable.
To stringify a #define you need to use a two-step approach:
#define _STRINGIFY(s) #s
#define STRINGIFY(s) _STRINGIFY(s)
...
#define SEED 123
...
const char * pszSeed = STRINGIFY(SEED); /* 'pszSeed' would point to "123" form here on. */
If you only want to use one character simply access it via *pszSeed or pszSeed[0].
Related
I have read lots on stringizing macros, but I obviously don't quite understand. I wish to make a string where the argument to the macro needs to be evaluated first. Can someone please explain where I am going wrong, or perhaps how to do this better?
#define SDDISK 2 // Note defined in a library file elsewhere ie not a constant I know)
#define DRIVE_STR(d) #d ":/"
#define xDRIVE_STR(x) DRIVE_STR(x)
#define FILEPATH(f) xDRIVE_STR(SDDISK + '0') #f
const char file[] = FILEPATH(test.log);
void main(void)
{
DebugPrint(file);
}
The output is: "2 + '0':/test.log",
But I want "2:/test.log"
The C PREprocessor runs before the compiler ever sees the code.
This means that the equation will not be evaluated before it is stringified; instead, the preprocessor will just stringize the whole equation.
In your case just removing the +'0' will solve the problem as the value of SDDISK does not need casting to a char before it is stringified.
However, should you actually need to perform a calculation before stringizing you should either:
Use cpp's constexpr.
Complain to your compiler vendor that a constant expression was not optimized.
Use a preprocessor library to gain the wanted behaviour.
I'm working in a C program and I came across a problem. I have this
#define NUMBER_OF_OPTIONS 5
#define NAME_OPTION1 "Partida Rapida"
#define NAME_OPTION2 "Elige Nivel"
#define NAME_OPTION3 "Ranking"
#define NAME_OPTION4 "Creditos"
#define NAME_OPTION5 "Exit"
for (iterator = 1; iterator <= NUMBER_OF_OPTIONS; iterator++){
menu_options[iterator-1]= NAME_OPTION + iterator
}
I want that "NAME_OPTION + iterator" takes the value of the corresponding #define. For example if the variable "iterator" is equal to one, I want menu_options[iterator-1] to take the value of NAME_OPTION1, which is "Partida Rapida".
How can I get this?
Essentially, you can't. #define macros are handled by the C Preprocessor and do textual substitution wherever that macro appears in the code. The macro NAME_OPTION has not been defined, so the compiler should complain. C does not allow appending numbers onto strings, or especially onto symbols like NAME_OPTION. Use an array of const char*, which you can then refer to with your iterator.
You can't use defines as this, you can do:
const char *menu_options[5] = {
"Partida Rapida",
"Elige Nivel",
"Ranking",
"Creditos",
"Exit"
};
If you use #define macro, you just tell preprocessor to replace every occurence of defined word by something else before the code is compiled into machine code.
In this case NUMBER_OF_OPTIONS will be replaced by 5, but there's no occurence of NAME_OPTION*, so nothing will be replaced and you'll probably get an error while preprocessing.
Piere's solutions shows how to do it, but I highly doubt that there's an iterator over char *array, so you have to iterate over given array using an integer index.
When using C preprocessor one can stringify macro argument like this:
#define TO_STRING(x) "a string with " #x
and so when used, the result is as follows:
TO_STRING(test) will expand to: "a string with test"
Is there any way to do the opposite? Get a string literal as an input argument and produce a C identifier? For example:
TO_IDENTIFIER("some_identifier") would expand to: some_identifier
Thank you for your answers.
EDIT: For those wondering what do I need it for:
I wanted to refer to nodes in a scene graph of my 3D engine by string identifiers but at the same time avoid comparing strings in tight loops. So I figured I'll write a simple tool that will run in pre-build step of compilation and search for predefined string - for example ID("something"). Then for every such token it would calculate CRC32 of the string between the parenthesis and generate a header file with #defines containing those numerical identifiers. For example for the string "something" it would be:
#define __CRC32ID_something 0x09DA31FB
Then, generated header file would be included by each cpp file using ID(x) macros. The ID("something") would of course expand to __CRC32ID_something, so in effect what the compiler would see are simple integer identifiers instead of human friendly strings. Of course now I'll simply settle for ID(something) but I thought that using quotes would make more sense - a programmer who doesn't know how the ID macro works can think that something without quotes is a C identifier when in reality such identifier doesn't exist at all.
No, you can't unstringify something.
//unstringify test
enum fruits{apple,pear};
#define IF_WS_COMPARE_SET_ENUM(x) if(ws.compare(L#x)==0)f_ret=x;
fruits enum_from_string(wstring ws)
{
fruits f_ret;
IF_WS_COMPARE_SET_ENUM(apple)
IF_WS_COMPARE_SET_ENUM(pear)
return f_ret;
}
void main()
{
fruits f;
f=enum_from_string(L"apple");
f=enum_from_string(L"pear");
}
You can create an identifier from a string, this operation is called token-pasting in C :
#define paste(n) x##n
int main(){
int paste(n) = 5;
printf("%d" , x5);
}
output : 5
How to write C program without using Main...!
When I'm learning how to write ASM file by for a simple C file [of length 3 lines], I got this doubt.
I assembly file I used preamble and post ambles, at function.
There is a great article and creating the smalest possible elf binary here. It has a lot of info of what is required to have something runnable by the os.
This is logical trick. Those who are unaware of it, can learn this trick.
#include<stdio.h>
#include<conio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)
void begin()
{
clrscr();
printf("\nHello !!! Kaushal Patel.");
getch();
}
Explanation :
The
pre-processor directive #define with arguments is used to give an impression
that the program runs without main(). But in reality it runs with a
hidden main().
The ‘##‘
operator is called the token pasting or token merging operator. That is
how, I can merge two or more characters with it.
#define decode(s,t,u,m,p,e,d) m##s##u##t
The macro
decode(s,t,u,m,p,e,d) is being expanded as “msut” (The ## operator
merges m,s,u & t into msut). The logic is when I pass
(s,t,u,m,p,e,d) as argument it merges the 4th,1st,3rd & the 2nd
characters.
#define begin decode(a,n,i,m,a,t,e)
Here the
pre-processor replaces the macro “begin” with the expansion
decode(a,n,i,m,a,t,e). According to the macro definition in the previous
line the argument must be expanded so that the 4th, 1st, 3rd & the
2nd characters must be merged. In the argument (a,n,i,m,a,t,e)
4th,1st,3rd & the 2nd characters are ‘m’,’a’,’i’ & ‘n’.
So the third line “void begin” is replaced by “void main” by the pre-processor before the program is passed on for the compiler.
Source :
http://ctechnotips.blogspot.in/2012/04/writing-c-c-program-without-main.html
Here is your answer:->
#include <stdio.h>
extern void _exit(register int);
int _start(){
printf(“Hello World\n”);
_exit(0);
}
I am new at C programming. I thought when you type something like #define Const 5000 that the compiler just replaces every instance of Const with 5000 at compile time. Is that wrong?
I try doing this in my code and I get a syntax error. Why can't i do this?
#define STEPS_PER_REV 12345
... in some function
if(CurrentPosition >= STEPS_PER_REV)
{
// do some stuff here
}
The compiler complains about the if statement with a syntax error that gives me no details.
the people in the comments are right. You almost definitely have a semicolon at the end of your #define. This means that your assignment becomes:
CURRENT_POSITION = 12345;;
(assuming that you HAD a semicolon at the end of the line...)
but your if becomes:
if(CurrentPosition >= 12345;)
which is of course invalid.
remember, #defines are NOT C code. They don't need semicolons.
Your code fragment is correct. #define is literally a string subsitution (with a bit more intelligence).
You can check what the preprocessor is doing in gcc by using the -E option, which will output the code after the pre-processor has run.
You are correct in that the C preprocessor will just replace STEPS_PER_REV with 12345. So your if statement looks fine, based on the code you provided.
To get to the bottom of this, could you please post your code and the actual contents of the error message.
You are right when you say that the compiler replaces every instance with the content of the macro. Check the type of CurrentPosition, probably the error is there.
Yes, but that should be a const, not a macro. You probably getting the wrong type in your comparison.
#define in c are macros, they are used by c preprocessor to replace them when they're found. For example in your source code the
**#define MAX_VALUE 500**
*if( reservations < **MAX_VALUE** )*
{
......
}
will be become into
*if( reservations < **500**)*
{
......
}
after preprocessing step. So that they could be used in boolean statetments in if sentences.