After working for more than 10 years, today a code caught my eye, I am unable to understand the function name defined inside a function gets printed in the output/log without being passed as an argument in macro or being defined as a global variable. Please help me understanding the internal. Please see the screenshot for the reference.
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
Output:
Hello WorldMAIN
C preprocessor macros simply do text replacement. They have no semantic awareness of your program.
This:
#include <stdio.h>
#define x printf("%s", f);
int main()
{
char* f = "MAIN";
printf ("Hello World");
x;
return 0;
}
Becomes:
#include <stdio.h>
int main()
{
char* f = "MAIN";
printf ("Hello World");
printf("%s", f);;
return 0;
}
Please note that if there is no f declared when this macro is used, you will see a compiler error. If f is declared, but is not a char *, you should see compiler warnings.
Some preprocessor macro best practices include (but are not limited to) using capitalized names, as x by convention looks like a variable or function name; and being careful about what syntactically significant symbols (in this case ;) you include in your macro text.
Hopefully this example was done for the sake of learning, because it is wholly unnecessary. Preprocessor macros wouldn't exist if they didn't serve a purpose, but beware they can easily obfuscate code.
Preprocessor macros are just text replacements. All #include statements are replaced with the content of the specified files. All occurrences of #define'd symbols are replaced with their specified text. All comments are omitted. Etc...
So, in your example:
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
The preprocessor replaces all instances of x with the text printf("%s", f); before the processed code is then sent to the compiler. So, this is the code that the compiler actually sees:
// contents of <stdio.h> here...
int main() {
char *f = "MAIN";
printf("Hello World");
printf("%s", f);;
return 0;
}
Related
I'm trying to create a function that takes in a variable and print out it name
It'd look something like this
#include <stdio.h>
void print_name(int a);
int main()
{
int a_random_name;
print_name(a_random_name);
return 0;
}
The output:
a_random_name
How would i be able to do this in c ?
As discussed in the comments, you cannot use a function to do so, but a macro:
#include <stdio.h>
#define print_name(x) (sizeof (x), printf("%s\n", #x))
void foo() {}
int main()
{
int a_random_name;
print_name(a_random_name);
print_name(foo);
return 0;
}
// Prints:
// a_random_name
// foo
Note that the (sizeof (x), part of the macro is here to make sure that the variable exists.
More information on macros manipulation:
https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing
https://gcc.gnu.org/onlinedocs/cpp/Macros.html
C11 macros specifications:
http://port70.net/~nsz/c/c11/n1570.html#6.10.3.2
This questions is about my homework.
This topic is need to use like:
#define GENERIC_MAX(type)\
type type##_max(type x, type y)\
{\
return x > y ? x : y;\
}
The content of the question is to make this code run normally:
#include <stdio.h>
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
The result of the operation is like this:
i=5.2000
j=3
And this code is my current progress, but there are have problems:
#include <stdio.h>
#define printname(n) printf(#n);
#define GenerateShowValueFunc(type)\
type showValue_##type(type x)\
{\
printname(x);\
printf("=%d\n", x);\
return 0;\
}
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
I don’t know how to make the output change with the type, and I don’t know how to display the name of the variable. OAO
This original task description:
Please refer to ShowValue.c below:
#include <stdio.h>
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
Through [GenerateShowValueFunc(double)] and [GenerateShowValueFunc(int)] these two lines macro call, can help us to generated as [showValue_double( double )] and [showValue_int( int )] function, And in main() function called. The execution result of this program is as follows:
i=5.2000
j=3
Please insert the code that defines GenerateShowValueFunc macro into the appropriate place in the ShowValue.c program, so that this program can compile and run smoothly.
A quick & dirty solution would be:
type showValue_##type(type x)\
{\
const char* double_fmt = "=%f\n";\
const char* int_fmt = "=%d\n";\
printname(x);\
printf(type##_fmt, x);\
return 0;\
}
The compiler will optimize out the variable that isn't used, so it won't affect performance. But it might yield warnings "variable not used". You can add null statements like (void)double_fmt; to silence it.
Anyway, this is all very brittle and bug-prone, it was never recommended practice to write macros like these. And it is not how you do generic programming in modern C. You can teach your teacher how, by showing them the following example:
#include <stdio.h>
void double_show (double d)
{
printf("%f\n", d);
}
void int_show (int i)
{
printf("%d\n", i);
}
#define show(x) _Generic((x),\
double: double_show, \
int: int_show) (x) // the x here is the parameter passed to the function
int main()
{
double i = 5.2;
int j = 3;
show(i);
show(j);
}
This uses the modern C11/C17 standard _Generic keyword, which can check for types at compile-time. The macro picks the appropriate function to call and it is type safe. The caller doesn't need to worry which "show" function to call nor that they pass the correct type.
Without changing the shown C-code (i.e. only doing macros), which I consider a requirement, the following code has the required output:
#include <stdio.h>
#define showValue_double(input) \
showValueFunc_double(#input"=%.4f\n" , input)
#define showValue_int(input) \
showValueFunc_int(#input"=%d\n" , input)
#define GenerateShowValueFunc(type) \
void showValueFunc_##type(const char format[], type input)\
{\
printf(format, input); \
}
/* ... macro magic above; */
/* unchangeable code below ... */
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
Output:
i=5.2000
j=3
Note that I created something of a lookup-table for type-specific format specifiers. I.e. for each type to be supported you need to add a macro #define showValue_ .... This is also needed to get the name of the variable into the output.
This uses the fact that two "strings" are concatenated by C compilers, i.e. "A""B" is the same as "AB". Where "A" is the result of #input.
The rest, i.e. the required function definition is very similar to the teacher-provided example, using the ## operator.
Note, this is if the variable name has to correctly be mentioned in the output.
With out the i = things would be easier and would more elegantly use the generated functions WITHOUT having the called showValue_double(i); be explicit macros. I.e. the functions generated are 1:1 what is called from main(). I think that might be what is really asked. Let me know if you want that version.
I have used the #pragma directive inside functions without error or warning(especially #pragma pack()).But the following code shows the warning incompatible implicit declaration of built-in function 'printf'|:
int main(void)
{
printf("Trial");
}
#include<stdio.h>
Further, here's is an extract from a book I have.The author has bad reviews on SO,especially for his generous use of void main(),but still I feel no author can be that bad to claim the following without reason:
Each of these preprocessor directives begin with a #
symbol. The directives can be placed anywhere in a program but
are most often placed at the beginning of a program, before the
first function definition.
So can you tell me whether it's mandatory to use some preprocessor directives like #include at the top of the program while others like #pragma can be used anywhere in the program?
Edit After OUAH's remark I tried the following, but it doesn't give warning,it gives a big pile of errors.LOL.
int main(void)
{
#include<stdio.h>
printf("Trial");
}
Think of it this way. The content of the included file is simply inserted at the point in the file where the #include directive appears. The resulting code needs to be syntactically correct for the language that you are programming in.
Confider the following file:
int a;
int foo();
int main()
#include "myheader.h"
int foo()
{
return 0;
}
And the file myheader.h contains:
{
return foo();
}
The code that the compiler will see after the preprocessor has processed the #include directive is:
int a;
int foo();
int main()
{
return foo();
}
int foo()
{
return 0;
}
This is valid C syntax. Such use of the #include directive is not recommended, but it gives you an idea of what it means. If the myheader.h file had the following content:
this is some garbage
which is not proper C
Then the resulting code will be:
int a;
int foo();
int main()
this is some garbage
which is not proper C
int foo()
{
return 0;
}
You can use #include at any point in the file. It results in literal inclusion of the content of the included file at that point. The reason you get a undeclared message for printf() in your code is that C requires a function be declared before use, and stdio.h has that declaration. Which is why it needs to be before it's use. And why it cannot be included in main() in the latter example is because on inclusion (expansion), it results in syntactically incorrect C code.
An #include directive can be placed anywhere in a source file, but in C an identifier can usually not be used before it has been declared. That's the reason why you put the #include directive at the begining of your source file.
void foo(void)
{
printf("Hello world\n");
}
extern int printf(const char *, ...); // Error, the declaration should be put
// before the actual call
"#pragma" directive will be ignored by C compiler since it considers the lines with "#" tag as comments. Looks like you are using openmp. The OpenMP compiler considers these(#pragma) as parallel directives. Hope this helps.
Can someone explain why the value of the variable test isn't changed when I run the short code snippet below?
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test = 'n';
printf("f1(&test)=%d. test's new value? : %c", f1(&test), test);
}
I know I'm probably missing something really simple. I just don't understand why test isn't changed in f1() because I'm passing it's address in, right? Why does it matter that the actual function call happens in the list of arguments to printf() ?
If I take the call to f1() out of the printf argument list like so:
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test='n';
int i;
i = f1(&test);
printf("f1(&test)=%d. test's new value? : %c", i, test);
}
things work as expected.
thanks in advance.
The order in which the arguments to a function call are evaluated is unspecified. Put another way, you can't tell for sure when f1(&test) will be evaluated.
So in your example, perhaps f1(&test) is evaluated after test: slightly counter-intuitively, you don't get to see the side effects of that invocation. But if you print test again after the call, you will indeed see them.
Bottom line, just be careful with function that have side-effects and you should be set.
There is no set order in which function parameters are evaluated. You're banking on the idea that the arguments are evaluated left to right, which can't be assumed.
Just change where you make your function call
#include <stdio.h>
int f1 (char* foo) {
*foo='a';
return 0;
}
int main(void)
{
char test='n';
f1(&test);
printf("test=%c\n", test);
return 0;
}
Could anyone please explain why this code compiles :
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv [])
{
FILE *ptr;
char string[10] = "Testing";
ptr = fopen("C:\\Users\\Jordan\\Desktop\\Hello.txt", "wb");
fwrite(string,sizeof(string[0]), sizeof(string)/sizeof(string[0]), ptr);
}
Yet this does not : Gives an Error C2065:'string' : undeclared identifer
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv [])
{
FILE *ptr;
ptr = fopen("C:\\Users\\Jordan\\Desktop\\Hello.txt", "wb");
char string[10] = "Testing";
fwrite(string,sizeof(string[0]), sizeof(string)/sizeof(string[0]), ptr);
}
I am using Visual Studio 2010 on a Windows 7 Machine.
Thanks
Visual Studio uses the old C89/90 C. In that older C version, you can't mix declarations and code.
All your declarations must go on top. That's why the second example fails to compile.
// This a declaration
FILE *ptr;
// This is code
ptr = fopen("C:\\Users\\Jordan\\Desktop\\Hello.txt", "wb");
// This is another declaration. Not Allowed in C89/C90!!!
char string[10] = "Testing";
In (the C89 version of) C, all variables must be declared at the top of the block (the function, in this case). In your first example, you're doing that, in your second one you're not.
If you saved this file with a .c extension the compiler is interpreting it as a C source file, and since VC++ support for C is for C89, the C89 rules for variable declaration apply; in particular, in C89 you must declare all the local variables at the beginning of their block.