Define constant inside #ifdef in C - c

I want to define a constant depending on the OS in use.
As such:
#include <stdio.h>
#ifdef _Win32 //Used for system("cls") command
#include <process.h>
#define CLEAR "system(\"cls\")"
#endif
#ifdef __APPLE__
#define CLEAR "system(\"clear\")"
#endif
int main()
{
CLEAR;
}
Xcode gives me an error stating that expression result unused at
#define CLEAR "system(\"clear\") and inside the main function.
I am on a Mac.

Use:
#define CLEAR system("clear")
not
#define CLEAR "system(\"clear\")"
You get the error because your macro call is substituted with:
"system(\"clear\")";
which is a useless expression statement (the expression being the string here) like for example:
0; // valid but pointless

try altering your main function as such:
int main()
{
int rc;
rc = CLEAR;
return rc;
}
You need to catch the return value of the system() call and use it

#define CLEAR system("clear")
and not
#define CLEAR "system(\"clear\")"
The compiler will create a new C code (called pre-processor code) in which will replace the macro name by its content.
so if you define macro in this way:
#define CLEAR "system(\"clear\")"
You will get in the new code (pre-processor code) generated by the Compiler:
int main()
{
"system(\"clear\")";
}
You can see the code generated by the compiler (pre-processor code) with gcc -E

Related

Functions parameters using macro

I wanted to know if it was contraindicated to define functions parameters using a macro, knowing they could be variable. Does it break a coding convention ?
example:
#ifdef PREVIOUSLY_DEFINED_MACRO
# define PARAMETERS int a, long b
#else
# define PARAMETERS int a
#endif
void my_func(PARAMETERS)
{
...
}
Thanks !
The code is completely valid but, it's not a good coding practice.
Let's assume the following code snippet:
#ifdef PREV_DEFINED
#define ARGS int x, int y
#else
#define ARGS int x
#endif
#include <stdio.h>
// #define PREV_DEFINED
int func(ARGS) {
// In this context, only 'x' is available
// set by the macro
return (x + y); // ERROR, 'y' is undefined
// You need to make a different code, specifically for
// #ifdef PREV_DEFINED and #else
}
To solve this, you need to make two or more different functions within those #ifdef and #endif flags whose usage is controlled by the PREV_DEFINED macro that depends on how many parameters could be variadic. Eventually, this will make the code look worse.

How can I make for loop of #define function?

I have #define function with argument such as DEF_GLOBAL_STRUCT(index) and I need to call this macro from 1 to 100. What is the best way? Can I use for loop?
I made the simple code to show my problem.
#include <stdio.h>
#include <stdint.h>
#define DEF_GLOBAL_STRUCT(index) uint8_t m_##index##_size=2; \
uint32_t m_##index##_data1=0; \
uint32_t m_##index##_data2=0;
DEF_GLOBAL_STRUCT(1)
DEF_GLOBAL_STRUCT(2)
DEF_GLOBAL_STRUCT(3)
// ...
DEF_GLOBAL_STRUCT(100)
int main()
{
printf("%u\n", m_1_size);
return 0;
}
Instead of 100 lines of define function call, can I use something like for loop. Or is there any other solution?
If I have all the control of the code I can define structure and declare it with array. But I can't do it. I need to use this type of define function. That is my limitation.
Your question is asking if you can mix C language with Preprocessor directives to automate the generation of code using both C language and Preprocessor directives.
The answer is not in the way you are trying to do it because of how the Preprocessor and the C compiler work.
The Preprocessor is a separate step from compilation. The idea is that the Preprocessor does a text replacement step of the C source code file to generate a new, temporary version of the C source code file which is then compiled by the C compiler.
It is two different steps and first the Preprocessor does its work and then the C compiler does its work.
What I would suggest is to write a simple program that generates an include file that contains the list of definitions you want to use. Then in the place where you want to put those definitions, use the #include directive to include it at that point.
So if you have a simple script or perhaps a C program something like:
#include <stdio.h>
int main ()
{
int i;
for (i = 1; i <= 100; i++) printf ("DEF_GLOBAL_STRUCT(%d)\n", i);
return 0;
}
Then you compile it and run it from a command line redirecting the output as in:
mygen >junk.h
then in the place you need these directives:
#include <stdio.h>
#include <stdint.h>
#define DEF_GLOBAL_STRUCT(index) uint8_t m_##index##_size=2; \
uint32_t m_##index##_data1=0; \
uint32_t m_##index##_data2=0;
#include "junk.h"
int main()
{
printf("%u\n", m_1_size);
return 0;
}
You can save some typing by defining another macro:
#include <stdio.h>
#include <stdint.h>
#define DEF_GLOBAL_STRUCT(index) uint8_t m_##index##_size=2; \
uint32_t m_##index##_data1=0; \
uint32_t m_##index##_data2=0;
#define DEF_GLOBAL_STRUCT_DECADE(tens) \
DEF_GLOBAL_STRUCT(tens##0) \
DEF_GLOBAL_STRUCT(tens##1) \
DEF_GLOBAL_STRUCT(tens##2) \
DEF_GLOBAL_STRUCT(tens##3) \
DEF_GLOBAL_STRUCT(tens##4) \
DEF_GLOBAL_STRUCT(tens##5) \
DEF_GLOBAL_STRUCT(tens##6) \
DEF_GLOBAL_STRUCT(tens##7) \
DEF_GLOBAL_STRUCT(tens##8) \
DEF_GLOBAL_STRUCT(tens##9)
DEF_GLOBAL_STRUCT(1)
DEF_GLOBAL_STRUCT(2)
DEF_GLOBAL_STRUCT(4)
DEF_GLOBAL_STRUCT(5)
DEF_GLOBAL_STRUCT(6)
DEF_GLOBAL_STRUCT(7)
DEF_GLOBAL_STRUCT(8)
DEF_GLOBAL_STRUCT(9)
DEF_GLOBAL_STRUCT_DECADE(1)
DEF_GLOBAL_STRUCT_DECADE(2)
DEF_GLOBAL_STRUCT_DECADE(3)
DEF_GLOBAL_STRUCT_DECADE(4)
DEF_GLOBAL_STRUCT_DECADE(5)
DEF_GLOBAL_STRUCT_DECADE(6)
DEF_GLOBAL_STRUCT_DECADE(7)
DEF_GLOBAL_STRUCT_DECADE(8)
DEF_GLOBAL_STRUCT_DECADE(9)
DEF_GLOBAL_STRUCT(100)
int main()
{
printf("%u\n", m_1_size);
return 0;
}

Stripping specific functions on compile time

I'm writing a C program that uses a custom logging function to debug my program. Whenever I compile my program as a release version, I want all of my logging functions to be stripped from the code so it won't show up if someone tries to disassemble it.
Take the following example:
#include <stdio.h>
void custom_logging_function(char* message)
{
// Do something here
}
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
How could I make it so that the custom_logging_function and it's arguments aren't compiled into my program without having to write include guards everywhere throughout my code? Thank you
You can use pre-processor flags, for example:
#include <stdio.h>
#ifdef DEBUG
void custom_logging_function(char* message)
{
// Do something here
}
#else
#define custom_logging_function(x) ((void) 0)
#endif
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
With this code you will have to tell the "debug" target to define DEBUG, if you want to define something specifically for the "release" target you can replace #ifdef DEBUG with #ifndef NDEBUG and add the NDEBUG flag to the "release" definitions.
Edit:
Changed #define custom_logging_function(x) 0 to #define custom_logging_function(x) ((void) 0) inspired by #JoachimPileborg his answer.
Assuming you only want the logging calls to happen in a debug-build of your application, and not the release build you send to customers, you can still use the preprocessor and conditional compilation for it. It can be made vert simple though by using macros instead of having checks at every call.
Something like this in a heder file:
#ifdef _DEBUG
void custom_logging_function(char* message);
#else
# define custom_logging_function(message) ((void) 0)
#endif
You could use an empty macro body for the release-macro, but that can cause some compilers to give "empty statement" warnings. Instead I use an expression casted to void (to tell the compiler that the result of the expression will not be used). Any smart compiler will not include the expression after optimization.

How to override assert macro in C?

I want to create my own version of assert in which it does some log prints in case assert was called in NDEBUG mode.
I tried to do the LD_PRELOAD trick and redefine the assert macro but it seems to ignore the macro definition completely and overriding __assert_fail is irrelevant since it isn't called in case of NDEBUG.
How can I override the libc assert macro?
I do not want to create a different function since assert is already used heavily in the project.
Had the same problem using gcc on Cygwin/Windows and on Linux.
My solution is to overwrite the (weak) definition of the actual assertion failed handling function. Here is the code:
/*!
* Overwrite the standard (weak) definition of the assert failed handling function.
*
* These functions are called by the assert() macro and are named differently and
* have different signatures on different systems.
* - On Cygwin/Windows its __assert_func()
* - On Linux its __assert_fail()
*
* - Output format is changed to reflect the gcc error message style
*
* #param filename - the filename where the error happened
* #param line - the line number where the error happened
* #param assert_func - the function name where the error happened
* #param expr - the expression that triggered the failed assert
*/
#if defined( __CYGWIN__ )
void __assert_func( const char *filename, int line, const char *assert_func, const char *expr )
#elif defined( __linux__ )
void __assert_fail ( const char* expr, const char *filename, unsigned int line, const char *assert_func )
#else
# error "Unknown OS! Don't know how to overwrite the assert failed handling function. Follow assert() and adjust!"
#endif
{
// gcc error message style output format:
fprintf( stdout, "%s:%d:4: error: assertion \"%s\" failed in function %s\n",
filename, line, expr, assert_func );
abort();
}
The C99 rationale provides a sample on how to redefine the assert in a good way on page 113:
#undef assert
#ifdef NDEBUG
#define assert(ignore) ((void)0)
#else
extern void __gripe(char *_Expr, char *_File, int _Line, const char *_Func);
#define assert(expr) \
((expr) ? (void)0 :\
__gripe(#expr, _ _FILE_ _,_ _LINE_ _,_ _func_ _))
#endif
I'd include assert.h right before this code to make sure assert.h is used.
Also notice that it calls a function that would do reporting logic, so that your code would be smaller.
It is a pretty simple thing to do, since assert is a macro. Given that you have this code:
#define NDEBUG
#include <assert.h>
int main( void )
{
assert(0);
return 0;
}
Then just do:
#ifdef NDEBUG
#undef assert
#define assert(x) if(!(x)){printf("hello world!");} // whatever code you want here
#endif
Note that this has to be done after #include <assert.h> though.
So if you want to stick your own definition into a common header file, and then use that header file to modify existing code, then your header file have to be included after assert.h.
my_assert.h
#include <assert.h>
#include <stdio.h>
#ifdef NDEBUG
#undef assert
#define assert(x) if(!(x)){printf("hello world!");}
#endif
main.c
#define NDEBUG
#include <assert.h>
#include "my_assert.h"
int main( void )
{
assert(0); // prints "hello world!"
assert(1); // does nothing
return 0;
}
An attempt to try to override the assert() macro in a large codebase can be difficult. For example, suppose you have code like:
#include <assert.h>
#include "my_assert.h"
#include "foo.h" // directly or indirectly includes <assert.h>
After this, any use of assert() will again use the system assert() macro and not the one that you have defined in "my_assert.h" (this is apparently part of the C design of the assert macro).
There are ways to avoid this, but you have to use nasty tricks like putting your own assert.h header in the include path before the system assert.h, which is somewhat error prone and non-portable.
I'd recommend using a different named macro than assert, and use regex tricks or a clang-rewriter to rename the various assert macros in your codebase to an assert macro that you can control. Example:
perl -p -i -e 's/\bassert\b *\( */my_assert( /;' `cat list_of_filenames`
(then adding "my_assert.h" or something like it to each of the files modified)
You can check if NDEBUG is defined and if it is then print whatever logs you want to print.

Define with only 1 argument

I'm reading external C code, and I found the following line of code:
#define __MAIN_C__
where #define is given only one "argument" (namely __MAIN_C__).
Is this just a placeholder, or can it have a function?
That #define will define __MAIN_C__ to no value (thanks to n.m. and a simple test program). It's a shortcut when you need something #defined when you don't care what it's defined to. In that case, somewhere in your code, you'd probably just see:
#ifdef __MAIN_C__
And that doesn't care what specific value it has, as long as it's defined (and perhaps nonzero).
You'll very often see this for include guards, like so:
#ifndef MYHEADER_H
#define MYHEADER_H
// stuff here
#endif
This is similar to doing this in the compile flags:
gcc -D__MAIN_C__ main.c
If you want to see that it's defined to nothing, try to compile this and watch it fail:
#include <stdio.h>
#define TEST
int main(int argc, char *argv[])
{
printf("%d\n", TEST);
return 0;
}
Yes, this can accomplish something. If you look, there's a pretty decent chance you'll find something like: #ifdef __MAIN_C__ somewhere -- this just checks whether the symbol has been defined, regardless of the value (if any) given.
A define in this case simply sets MAIN_C. No value is assigned, but the preprocessor will interperet MAIN_C as "true". Generally, defines like these are used to include or exclude code before compilation, using something like the following:
#define WIN32
#ifdef WIN32
//some win32-specific code
#else
//some other code
#endif
This definition makes __MAIN_C__ to expand (roughly speaking) to nothing.
A possible use:
#ifdef __MAIN_C__
foo(bar);
#endif
Another one:
#ifdef PLAIN_OLD_OS
#define __MAIN_C__
#else
#define __MAIN_C__ __os_specific_attribute(dllsomething)
#endif
__MAIN_C__ int main (int argc, char* argv[]) {

Resources