How to implement a macro in C - c

Hi This is legal code for the compiler I use:
#use delay(clock=4M)
now I need to substitute the inside brackets text clock=4M with a macro.
The digit 4 might be any digit, it should be modifiable.
I tried with this
#define CLOCK_SPEED(x) clock=xM
but didnt work.

What you want is the preprocessor concatenation operator, ##.
#define CLOCK(x) clock=x##M
void some_function() {
CLOCK(4);
}
The outcome:
tmp$ cpp -P test.c
void some_function() {
clock=4M;
}
On a side note, macros like these are often the cause of hard-to-find bugs. It is usually recommended to write them like this:
#define CLOCK(x) do { clock=x##M; } while(0)

Related

C: How to Shield Commas in Macro Arguments?

Is there a general method to shield comments in macro arguments in C? I know that parentheses can be used for this purpose, but that will not work in cases where added parentheses result in syntax errors in the macro output. I've heard that ({ }) works to shield commas in GCC, but I need this code to also work in VC++ (one of the recent versions which does conform to the C standard with regard to commas in macros). I also cannot use variadic macros in my case.
The specific case I'm trying to do is this (lengthof is a macro defined elsewhere). I'm trying to write a single macro for the entire thing because this will be used many times, and having a multi-macro solution would add a large amount of additional testing code.
#define TEST_UNFUNC(func, res_type, res_set, op_type, op_set) \
{ \
static const res_type res[] = res_set; \
static const op_type op[] = op_set; \
int i; \
for (i = 0; i < MIN(lengthof(res), lengthof(op)); i++) \
assert(func(op[i]) == res[i]); \
}
If possible I would like a general answer and not merely a workaround specific to this particular macro.
Use parentheses to shield the comma, and then pass them through a special unparen macro, defined in the example below:
#include <stdio.h>
#define really_unparen(...) __VA_ARGS__
#define invoke(expr) expr
#define unparen(args) invoke(really_unparen args)
#define fancy_macro(a) printf("%s %s\n", unparen(a))
int main()
{
fancy_macro(("Hello", "World"));
}
The trick here is that the invoke macro forces an extra expansion, allowing really_unparen to be called even though it's not followed by parentheses in the source.
Edit: per comment below, this appears to not be necessary in this case. Though I'm sure I've hit a case where I needed it sometime ... and it doesn't hurt.

GCC __func__ gets evaluated to an empty string

Given the following code in a project I'm working on:
/* Pre-definitions in a pre-definitions file to be included in the project */
#ifdef WIN32
#define __FUNCNAME__ __FUNCTION__
#else
#define __FUNCNAME__ __func__
#endif
/* My definitions */
#define MAC() \
MAC1()
#define MAC1() \
myPrintFunction(__FUNCNAME__)
/* My print function */
void myPrintFunction(const char * functionName)
{
printf("\n func name: %s \n",functionName);
}
/* Macro usage example function */
void myFunction()
{
if (some_condition)
{
MAC();
}
}
The function name is presented as an empty string.
Any idea why, and how can I fix it?
Code compiled and tested on Linux machine, using GCC compiler.
Use __func__ out of the box. It's been part of the C standard since C99. Change your compiler settings to use at least that standard.
Note that __func__ is not a macro but a predefined identifier which takes the form such that writing it anywhere within a function body is exactly equivalent to using it at that point, having first written
static const char __func__[] = "function-name";
just after the opening brace of a function body.
Formally the behaviour of your current code is undefined. Any symbol containing two consecutive underscores is reserved by the system. (That includes macro names, function names, and variable names.)
Your code as presented gives the expected result (once I'd added the necessary includes and main):
#include <stdio.h>
#ifdef WIN32
#define __FUNCNAME__ __FUNCTION__
#else
#define __FUNCNAME__ __func__
#endif
/* My definitions */
#define MAC() \
MAC1()
#define MAC1() \
myPrintFunction(__FUNCNAME__)
void myPrintFunction(const char * functionName)
{
printf("\n func name: %s \n",functionName);
}
int main()
{
MAC();
}
I compiled this using gcc -std=c11 -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds with no warnings.
You should really post a complete (but minimal) example that actually compiles, along with the compiler flags you used, as something must certainly be different to explain the symptoms you describe.
Also, when writing statements as macros, you may find it helpful to use the do {...} while (0) idiom to avoid unexpected expansions changing the control flow.

C-Macro in if-Condition

quite a simple problem I have here.
I have a little Macro for a global Variable which is defined in my Header like this:
extern bool uart_message_received;
#define get_uart_message_rec() uart_message_received;
In my C-File I want to access the file like this:
bool uart_message_received = 0;
void foo(void)
{
bool test;
test = get_uart_message_rec(); // Works fine
if(get_uart_message_rec()==0) // Doesn't work
{
//...
}
}
I am a little confused why the condition in the if is not working. Am I doing something wrong, or am I violating some C directives?
#define get_uart_message_rec() uart_message_received
// ^ no semicolon
Macro replacement will substitute the text as is, including the ; in your case. Which will lead to syntax errors in the if case.
Remove the colon at the end of :
#define get_uart_message_rec() uart_message_received;
Because it becomes:
if(**uart_message_received;**==0) // Doesn't work
{
//...
}
When the preprocessor basically does find/replace on your code.
You have a semicolon on the end of your macro - remove that, and it will be fine. Note that macros do replace exactly as written, so your macro expands from:
if(get_uart_message_rec()==0)
to:
if(uart_message_received; ==0)
which should make the compiler error.
[writing too slowly!]
It's because you have a semicolon at the end of the macro.
Macros are replaced as is, before the actual compiler sees the text, so the statement after replacement looks like this:
if(uart_message_received;==0)

C macro trick for selective replace

Is there a macro trick to rename just the function calls without affecting the function definition, specifically for gcc/cpp:
#define get_resolution __mock_get_resolution
The above macro changes all places, but I just want this to take effect for the function call get_resolution(); without affecting the definition void get_resolution()
void get_resolution()
{
}
void display()
{
get_resolution();
}
As gcc-specific solution,
The `alias' attribute causes the declaration to be emitted as an
alias for another symbol, which must be specified. For instance,
void __f () { /* Do something. */; }
void f () __attribute__ ((weak, alias ("__f")));
No, the C preprocessor has no semantic knowledge of the structure of the C program, it just sees text tokens.
One option would be to #undef the macro before the definition and redefine it afterwards, but this is messy. Another option would be to add a macro to the definition of each function you want to mock like this:
#if DO_MOCKING
#define IMPLEMENT_MOCKABLE_FUNCTION(funcname) _real_ ## funcname
#define get_resolution _mock_get_resolution
#else
#define IMPLEMENT_MOCKABLE_FUNCTION(funcname) funcname
#endif
...
void IMPLEMENT_MOCKABLE_FUNCTION(get_resolution)()
{
...
}
Also note that identifiers beginning with two underscores, as well as identifiers beginning with an underscore followed by a capital letter, are reserved by the implementation (i.e. the compiler and standard libraries). So I've renamed the identifiers in the example above to use a single underscore and a lowercase letter.
You could do something like this:
#define get_resolution __mock_get_resolution
somewhere globally accessible (like a header you always include etc.) and then do this:
#undef get_resolution
void get_resolution()
{
}
#define get_resolution __mock_get_resolution
void display()
{
get_resolution();
}
Ugly hack, but it will save you having to write a sed(1) script.
Test case follows:
$ gcc -o test test.c
$ ./test
__mock_up
$ cat test.c
#include <stdio.h>
#define get_resolution __mock_up
int
__mock_up()
{
printf("__mock_up\n");
}
#undef get_resolution
int
get_resolution()
{
}
#define get_resolution __mock_up
int main()
{
get_resolution();
return 0;
}
$

gcc warnings for no-effect statements.

I have a logging macro which in release mode becomes:
#define LOG (void)
So statement
LOG("foobar %d", 0xbabecafe);
is expanded to
(void)("foobar %d", 0xbabecafe);
The problem is that the last expression produces an warning under gcc:
warning: left-hand operand of comma expression has no effect [-Wunused-value]
How can I change the logging macro such that no warning is issued? (Note, that I don't want to add compiling flag -Wunused-value).
EDIT I see already a couple of answers involving (...). The same file is compiled under Minix which doesn't support variadic macros. The best would be to have a C89 conforming solution. While your answer is correct (and I upvoted it), it is my fault that I didn't include this small detail.
I think the old school way of dealing with this is to take advantage of double parens. Something like this:
LOG(("message: %d", 10));
Then for your macro, you define it like this:
#define LOG(x) printf x
or
#define LOG(x) (void)0
Because of the double parens, the pre-processor treats the whole inner paren as a single parameter. This at least used to work in visual studio.
EDIT: I did a quick test, it works with gcc with -ansi, so it should be good:
gcc -DNDEBUG -ansi -pedantic -W -Wall test.c -o test
#include <stdio.h>
#ifdef NDEBUG
#define LOG(x) printf x
#else
#define LOG(x) (void)0
#endif
int main() {
LOG(("message: %d\n", 10));
return 0;
}
The easiest should be
#define LOG(...) (void)0
(gcc supports the C99 variadic macros and most other compilers also do these days) That will discard the arguments list, which has two advantages:
it does not create statements with no effect and
the arguments are not evaluated at all (if you call non-inline functions in the argument list, in your version the compiler can't eliminate them, while with the variadic macro, the compiler won't see them at all.
#define LOG(...) seems to do the trick.
For your problems with a non-conforming C implementation (not even C89?) you could do something like
static void LOG(char *format, ...) { /* empty */ }
even a completely dumb compiler should be able to optimize that out.
I've used
#define LOG( t) t
for the development version and
#define LOG( t)
for the release version, with a typical use being
LOG( printf( "here\n"));

Resources