Use a preprocessor directive without using the # character - c

Is there a way to use a preprocessor directive without using the # character in C code?
Can we echo the hash character somehow by using its ASCII etc. equivalents?
Eg: 1 can be echoed by using 'SOH' in the .c source file. Is there a similar hack for
'#'?

You can use the digraph or trigraph equivalent if your compiler supports them (you may need to pass flags to the compiler):
digraph: %:
trigraph: ??=
However, if you're trying to use preprocessor macros to generate preprocessor commands, there's no way to do that.

Related

What is the difference between '#include' and '##include'?

For example:
#include "pathtoheader1/header1.hh"
##include "pathtoheader2/header2.hh"
What is the difference between these two preprocessor directives?
Edit
From what I can tell, the ##include directive, in the context of the program I am working with, will prepend -I flags to the specified include path.
TRICK_CFLAGS += -Imodels
TRICK_CXXFLAGS += -Imodels
The compiler will now look for:
/models/pathtoheader1/header1.hh
instead of
/pathtoheader1/header1.hh
These flags are stored in a .mk file.
Additional Information
I am using NASA's Trick Simulation environment to build a simple 2-body simulation of the earth orbiting the sun. The specific tool I am using is called 'trick-CP', Trick's compilation tool.
https://github.com/nasa/trick
## is the token pasting operator in both the C and C++ preprocessors. It's used to concatenate two arguments.
Since it requires an argument either side, a line starting with it is not syntactically valid, unless it's a continuation of a previous line where that previous line has used the line continuation symbol \ or equivalent trigraph sequence.
Question is about NASA Trick. Trick extends C and C++ language with its own syntax.
From Trick documentation:
Headers files, that supply data-types for user-defined models should be included using ##include . Note the double hash (#).
The second one is a syntax error in C++, and I am pretty sure it is a syntax error in C too. The ## preprocessor operator is only valid inside a preprocessor macro (where it forces token pasting).
Here is what the Trick Documentation says about include:
Include files
There are two types of includes in the S_define file.
Single pound "#" includes.
Include files with a single pound "#" are parsed as they are part of the S_define file. They are treated just as #include files in C or C++ files. These files usually include other sim objects or instantiations as part of the S_define file.
Double pound "#" includes.
Include files with a double pound "##" are not parsed as part of the S_define file. These files are the model header files. They include the model class and structure definitions as well as C prototypes for functions used in the S_define file. Double pound files are copied, minus one pound, to S_source.hh.
Also here is a link to where it talks about it in the Trick documentation: https://nasa.github.io/trick/documentation/building_a_simulation/Simulation-Definition-File

How to invoke the C preprocessor?

How can we invoke the C preprocessor in a C program, like if we want to prepend some of our files to the list of standard library files while using #include<file_name> using -I, what we should do?
Adding, if we want to add comments to the output of our program, I have heard that we can use -C invocation commands. How to do it? Somebody please correct me and explain further if I am wrong.
The mechanism you linked to is explicitly not to be supposed from within a program, but it is to use the preprocessor for other things, like text libraries etc.
So you can transform a text using the means of the C preprocessor and convert it to its "expanded" form, without compiling it (perhaps it is a configuration file or whatever).
For example, you can have a
commonpart.h:
[General]
foo=1
bar=2
#define VALUE 3
and a
cfg.tmpl
#include "commonpart.h"
// This is a commet which won't show up in the end
baz=VALUE
you can do cpp -P cfg.tmpl and thus compile all this to
[General]
foo=1
bar=2
baz=3

C compiler warning Unknown escape sequence '\.' using regex for c program

I am using regex to determine a command line argument has the .dat extension. I am trying the following regex:
#define to_find "^.*\.(dat)?"
For some reason I am getting the warning I stated in the title of this question. First, is this expression correct? I believe it is. Second, if it is correct, how can i get rid of this warning?
I am coding a c program in Xcode and the above #define is in my .h file.
Thanks!
The warning is coming from the C compiler. It is telling you that \. is not a known escape sequence in C. Since this string is going to a regex engine, you need to double-escape the slash, like this:
#define to_find "^.*\\.(dat)?"
This regex would match a string with an optional .dat extension, with dat being optional. However, the dot . is required. If you want the dot to be optional as well, put it inside the parentheses, like this: ^.*(\\.dat)?.
Note that you can avoid escaping the individual metacharacters by enclosing them in square brackets, like this:
#define to_find "^.*([.]dat)?"
You need
#define to_find "^.*\\.(dat)?"
Should do the trick as the \ needs to be escaped for C and not the benefit for regex at this stage

Problem with Microsoft Compiler macro expansion spaces

I have this problem in a header macro expansion under Microsoft C Compiler Preprocessor:
custom.h
.
.
# define _OTHER_INCLUDE_DIR C:\3rdparty\usr\include
# define _3RD_PARTY_HEADERS(headername) <_OTHER_INCLUDE_DIR\headername>
.
.
With a header test:
headertest.h
.
.
#include _3RD_PARTY_HEADERS(stdint.h)
.
Microsoft C preprocessor expand second line like(custom.h):
#include <C:\3rdparty\usr\include\headername>
If I set :
# define _3RD_PARTY_HEADERS(headername) <_OTHER_INCLUDE_DIR\ headername>
The result is:
#include <C:\3rdparty\usr\include\ stdint.h>
How I can fix that?
It looks like you want to juxtapose your directory and your header name. You use ##, like this:
# define _3RD_PARTY_HEADERS(headername) <_OTHER_INCLUDE_DIR\\##headername>
Is there no way to have the \ character sequences to be represented differently? The problem is that this is an escape character for C and C++. C99 explicitly states
If the characters ', \, ", //, or /*
occur in the sequence between the <
and > delimiters, the behavior is
undefined.
(There is a similar phrase for "..." includes.)
and I imagine that for C++ there must be something similar. So maybe you just could use / and the compiler would replace them internally to refer to the correct file on your system.
You know, most compilers have a command-line argument to add to the include path... -I or /I most likely for the Microsoft one. One doesn't usually do what you're doing here, never mind whether or not you can make it work.

gcc check if file is main (#if __BASE_FILE__ == __FILE__)

In ruby there's very common idiom to check if current file is "main" file:
if __FILE__ == $0
# do something here (usually run unit tests)
end
I'd like to do something similar in C after reading gcc documentation I've figured that it should work like this:
#if __FILE__ == __BASE_FILE__
// Do stuff
#endif
the only problem is after I try this:
$ gcc src/bitmap_index.c -std=c99 -lm && ./a.out
src/bitmap_index.c:173:1: error: token ""src/bitmap_index.c"" is not valid in preprocessor expressions
Am I using #if wrong?
As summary for future guests:
You cannot compare string using #if
BASE_FILE is the name of file that is being compiled (that Is actually what I wanted).
Best way to do this is to set flag during compilation with -D
in gcc you can use:
#if __INCLUDE_LEVEL__ == 0
or:
if(!__INCLUDE_LEVEL__)
to check if your inside the __BASE_FILE__
Yes, you are misusing #if. It only works on integer constant expressions. But even if you were using if, comparing pointers for equality is never a valid way to compare strings in C.
It seems you can't.
Alternatively, it works perfectly fine on a regular if condition, and gcc can optimize this nicely.
if (!strcmp(__BASE_FILE__, __FILE__)) {
// works.
}
but you can't define new main functions or use other preprocessor tricks. but you could short-circuit main by using static methods, but that's harsh and dirty.
But maybe you shouldn't do it. in Ruby/python, this works because usage of files is done at runtime. in C, all files are to be compiled to be used.
Keep in mind that most build system will build one file at a time, building them as object files, and rebuilding them only when necessary. So
__BASE_FILE__ and __FILE__
will be equals most of the time in sources files, if not always. And i would strongly discourage you to do this in header files.
It's easier to just put your tests in separate files, only linking them when needed.
Yup, as others say, you're misusing it since you can't compare strings that way in C, and especially not in the preprocessor.
The file that defines int main(int argc, char* argv[]) is the main file. There can be only one such function in an executable.
In addition to what others have said (you can't have the C preprocessor compare strings), be careful with __BASE_FILE__ because it may not correspond to your definition of "main" file. __BASE_FILE__ is the name of the file being compiled, so it's always equal to __FILE__ in source files, and only differs in headers and other included files.
In particular, __BASE_FILE__ is not the name of the file which contains the main() function.

Resources