0

I was trying to build a C project which has a rather unfamiliar way to define namespaces, eg. in file root.h

#define eval CRYPTO_NAMESPACE(eval) 

And in the Makefile the following appears (rule for make all):

gcc -O3 -g -march=native -mtune=native -Wall -I. -Isubroutines -DKAT -DKATNUM='cat KATNUM' "-DCRYPTO_NAMESPACE(x)=x" "-D_CRYPTO_NAMESPACE(x)=_##x" -o kat nist/kat_kem.c nist/rng.c benes.c bm.c controlbits.c decrypt.c encrypt.c gf.c operations.c pk_gen.c root.c sk_gen.c synd.c transpose.c util.c -I${PWD}/subroutines -L${PWD}/libs/ -lXKCP -lcrypto -ldl

What do these options do:

"-DCRYPTO_NAMESPACE(x)=x" "-D_CRYPTO_NAMESPACE(x)=_##x" 

I know that -DXXX=YYY is the same as #define XXX YYY. Now, why is it in double-quotes? Why it looks like a macro (may be it is)? Lastly, what does _##x mean?

5
  • You will have to improve formatting to make your question readable and answerable. stackoverflow.com/editing-help Commented Jul 18, 2021 at 20:54
  • 1
    This root.h:#define eval CRYPTO_NAMESPACE(eval) is very unclear. It is neither makefile syntax nor C syntax. Do you mean to express that the file named "root.h" contains a single line with a #define ? Please provide a more carefully represented minimal reproducible example of the different files in your project. Commented Jul 18, 2021 at 20:56
  • 1
    What is confusing you about the "-DCRYPTO_NAMESPACE(x)=x" "-D_CRYPTO_NAMESPACE(x)=_##x"? The meaning of -D, the preprocessor syntax and effect of ## ? Please be more precise about what you want explained. Do you understand the preprocessor effect of #define CRYPTO_NAMESPACE(x) x and #define _CRYPTO_NAMESPACE(x) _##x? Commented Jul 18, 2021 at 21:02
  • That's probably a terrible user interface, but concatentaion. Commented Jul 18, 2021 at 21:09
  • @Yunnosch Edited, hopefully it is clearer now Commented Jul 18, 2021 at 21:09

1 Answer 1

1

The macro in the header:

#define eval CRYPTO_NAMESPACE(eval) 

Replaces every token eval with CRYPTO_NAMESPACE(eval). So if the code contains

void eval(char *expr) { ... 

the preprocessor output - without any other definition - would be

void CRYPTO_NAMESPACE(eval)(char *expr) { ... 

The -D parameters effectively add two more definitions:

#define DCRYPTO_NAMESPACE(x) x #define _CRYPTO_NAMESPACE(x) _##x 

In our example, the first define causes the normal result to be re-written one more time:

void eval(char *expr) { ... 

so we're back where we started. A different definition could be used to change the compiled name of the function. This definition makes the header definition a no-op.

The second macro uses the token concatenation operator ##. It adds a prefix underscore _ to the macro argument. E.g. if the code contained something like:

void _CRYPTO_NAMESPACE(foo)(int x) { 

then the result is

void _foo(int x) { 

At a higher level, these macros allow names of things (in the first case anything named eval and in the second, any name at all) to be transformed uniformly throughout the program. This is a fairly standard workaround for name collisions in big C programs. If you have two source code bases that have both defined the same public function name, macros like this can be used to add a prefix or suffix that changes one or both names in the compiled code without modifying either original code. This is an important capability for long-term configuration management where manually editing externally furnished code bases isn't a serious option.

A wild guess is that this treatment is given to eval because the likelihood of some other chunk of C also defining a function named eval is extremely high.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.