I am using standard CPP to preprocess any C/CPP file.
I am using the below command for preprocessing:
cpp -idirafter <path_to_header_files> -imacros <sourcefile> <source_file> > <destination_file>
The above command is replacing all the macros with its corresponding implementations defined in header files.
If I want some specific MACROS containing a particular string (eg, ASSERT) should not replace by cpp preprocessor. ie, if any macro defined by the name of TC_ASSERT_EQ or TC_ASSERT_NEQ defined in some header files should not replace by preprocessor.
Is there any ways I can control this?
You can use predefined macros to work around this. You can pass different defines to cpp and gcc/g++ using -D parameters
For example your assertion header can look like my_assert.h:
#ifndef __my_assert_h__
#define __my_assert_h__
#if defined ASSERT_DEBUG
#define my_assert(expr) my_assert(expr) /* please dont touch my assertions */
#else
#define my_assert(expr) ((void)0U) /* Your assertion macro here */
#endif /* ASSERT_xxx */
#endif /* #ifndef __my_assert_h__ */
And your source files can be as before. For example test.c:
#include "my_assert.h"
#include <stdio.h>
void foo (int p) {
my_assert(p==1);
puts("Tralala\n");
}
int main (void) {
foo(1);
return 0;
}
With the above trick you can run
cpp -DASSERT_DEBUG test.c
While the compilation still works as before.
gcc test.c
I have used #pragma poison TC_ASSERT_EQ statements to pass the line without preprocessing.
Related
The following code does not compile:
#define SOME_MACRO(x,y) x+y
#define ADD_ONE_TO(x) SOME_MACRO(x,1)
#undef SOME_MACRO
int main(){
ADD_ONE_TO(1);
}
Is there any hack to either:
Prevent code duplication by having common functionality in SOME_MACRO and using it in other macros BUT undef`ing it to prevent its usage in common user-code.
Somehow making it so the ADD_ONE_TO macro just copy-pastes the macros it uses instead of referncing them.
Preventing user-code from accessing and using SOME_MACRO but allowing it to be used in other specific parts of code(other, select, macros)
Hide the implementation of macros by disallowing access(undef or otherwise) to the macros inside the macro which we want to hide the implementation of.
When using GNU CPP you could use #pragma GCC poison, for example:
#include <stdio.h>
#define print(...) printf(__VA_ARGS__)
#pragma GCC poison printf
int
main ()
{
print("hi, %s", "there!"); /* Ok */
printf("oh %s", "no!"); /* ERROR! use of poisoned keyword */
}
Tested and it works!
I'm trying to use Unity Builds to shorten the build time of a c++ project on Windows. One of several problems I met is the single file scope issue.
Once all source codes are included in a single source file, they all share the same file scope. All locally defined symbols using same name will be duplicate and causing compile errors.
Currently, I have to change each duplicated names with a file postfix to avoid duplication. But I think there might be better solutions.
I'd like to share my current solution.
In generation of unity_build_source_<index>.cpp files, define a UNITY_BUILD macro and wrap each include source code with macros:
// unity_build_souce file, automatically generated, do not edit manually.
#define UNITYBUILD_CONCATENATE_DETAIL(x, y) x##y
#define UNITYBUILD_CONCATENATE(x, y) UNITYBUILD_CONCATENATE_DETAIL(x, y)
#define UNITYBUILD_MAKE_UNIQUE(x) UNITYBUILD_CONCATENATE(x, _UNITYBUILD_COUNTER)
#define UNITY_BUILD
// for each source code
#define _UNITY_BUILD_COUNTER 1
#include <path/to/source1.cpp>
#undef _UNITY_BUILD_COUNTER
#define _UNITY_BUILD_COUNTER 2
#include <path/to/source2.cpp>
#undef _UNITY_BUILD_COUNTER
// ...
In source codes, use UNITYBUILD_MAKE_UNIQUE macro for names that is duplicated.
#ifdef UNITY_BUILD
#define a_duplicated_variable UNITYBUILD_MAKE_UNIQUE(a_duplicated_variable)
#define ADuplicatedClass UNITYBUILD_MAKE_UNIQUE(ADuplicatedClass)
#define aDuplicatedFunction UNITYBUILD_MAKE_UNIQUE(aDuplicatedFunction)
#endif
namespace
{
int a_duplicated_variable = 3;
class ADuplicatedClass
{
public:
ADuplicatedClass(int ){}
};
}
void aDuplicatedFunction()
{
ADuplicatedClass c(a_duplicated_variable);
}
#ifdef UNITY_BUILD
#undef a_duplicated_variable
#undef ADuplicatedClass
#undef aDuplicatedFunction
#endif
I know this solution is still bad looking. Compared with manually change each duplicated symbols, it keeps the old names the look as they were.
My question is quite straight forward. I just intended to know that is the #define directive in C++ controllable over the different project files? Elaborately, I have a header file and a cpp file for one project. The codes of the files are as follows:
MyHeader.h
#ifndef __MY_HEADER_H__
#include <cstring>
using namespace std;
#ifdef _HEADER_EXPORT_
#define HEADER_API __declspec(dllexport)
#else
#define HEADER_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
class HEADER_API MyHeader
{
public:
MyHeader();
~MyHeader();
#ifdef _HEADER_DISPLAY_
void __cdecl ParseHeader();
#elif defined (_HEADER_RETURN_)
string __cdecl ParseHeader();
#endif
};
#ifdef __cplusplus
}
#endif
#define __MY_HEADER_H__
#endif
MyHeader.cpp
#ifndef __MY_HEADER_H__
#include "MyHeader.h"
#endif
MyHeader::MyHeader() { }
MyHeader::~MyHeader() { }
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _HEADER_DISPLAY_
HEADER_API void __cdecl MyHeader::ParseHeader()
{
fputs(string("Displaying...").c_str(), stdout);
}
#elif defined (_HEADER_RETURN_)
HEADER_API string __cdecl MyHeader::ParseHeader()
{
string retVal("Returning...");
return retVal;
}
#endif
#ifdef __cplusplus
}
#endif
In another project HeaderImpl.cpp file has been implemented with the following code.
HeaderImpl.cpp
#include "stdafx.h"
#define _HEADER_DISPLAY_ // To display the message
// #define _HEADER_RETURN_ // To return the message as string
#include "MyHeader.h"
int main(int argc, char* argv[])
{
MyHeader header;
MyHeader.ParseHeader(); // To display the message or to return the string
return 0;
}
Now, I wanted to know that how can I use the #define directive in my HeaderImpl.cpp file to control the ParseHeader method for MyHeader.cpp file? As it has been noted that MyHeader.h file doing exactly what I need for; i.e. controlling the ParseHeader method upon declaring the #define directive, accordingly.
You can't. Each C++ source file is compiled independently, and settings in one cannot affect another. You'll have to do this on project level.
One way to do that would be to set up different project (and solution) configurations for different values of this macro. Instead of just the usual Debug and Release, you could add Debug-Display, Debug-Return etc. You can then define the macros in the project settings for each configuration. This will make sure you link the correctly built version of your library.
As a side note, you're using illegal names in your code. A name which contains double underscores, or starts with an underscore followed by an uppercase letter, is reserved for the compiler & standard library. User code is not allowed to use such names for its own purposes.
You usually can provide #defines for all of your compilation units on the command line of the compiler. IIRC for Visual studio that would be something like /D_HEADER_DISPLAY_ or /D_HEADER_RETURN_
Your project must be using something like this already for the _HEADER_EXPORT_ define.
There is no way for a preprocessor definition in one translation unit to remotely affect a different translation unit.
Most, if not all, compilers accept them as parameters for the compilation, though (and the flag is usually -D, or /D for VC++).
In Visual Studio, you can set project-wide preprocessor definitions in the project settings, under
Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions
I have a C++ class key_gen that has some data members of type paillier_ prvkey_t. The problem is that I cannot include paillier library (writen in c) in my header file say key_gen.h. But I can include it in my key_gen.cpp using
extern "C"{
#include<paillier.h>
}
I'm using cygwin to run my code, and I use command line as below:
g++ Key_Gen.cpp -L/cygdrive/c/cygwin/home/Win7/libpaillier -l:libpaillier.a -
-lgmpxx -lgmp
As soon as I include the paillier header into my header file cygwin alerts when I run the code.
The error contains many lines e.g:
In file included from Key_Gen.h:13:0,
from Key_Gen.cpp:2:
/usr/local/include/paillier.h:63:3: note: previous declaration as ‘typedef
struct paillier_pubkey_t paillier_pubky_t’} paillier_pubkey_t;
^
Can someone tell me how to resolve the problem?
When you tell a C or C++ compiler to process a file, foo.cpp, the first stage of compilation is pre-processing which expands macros, substitutes defines and expands pre-processor directives such as #include.
In the early days, the preprocessor was a separate program, and it generated the output on the fly: the C compiler itself didn't know about #include and all it saw was a single stream of code.
Today, the preprocessor is usually an integral part of the compiler (gcc, MSVC, etc) but the single-stream effect for each source file you specify on the command line remains the same, and you can still access the compiler to generate the output of pre-processing as a single intermediate file so that you can see what translations went on (-E option to gcc/g++). So if you write:
// Foo.h
int foo;
// Bar.cpp
#include "Foo.h"
int bar;
#include "Foo.h"
What the compiler sees is a single contiguous stream:
/* "Bar.cpp" from command line */
// Bar.cpp
/* "Foo.h" from Bar.cpp:2 */
int foo;
/* end "Foo.h" */
int bar;
/* "Foo.h" from Bar.cpp:4 */
int foo;
/* end "Foo.h" */
/* end "Bar.cpp" */
The compilation stage doesn't know about #include,
The pre-processor doesn't do de-duplication of #includes by default, so multiple includes produce duplication.
If you want to add paillier.h to your own .h file you will need to prevent this duplication. There are two common ways to do this.
pragma guard
At the start of the .h file use the pre-processor directive #pragma, understood by both the GNU C and C++ compilers:
#pragma once
Pro: The pre-processor detects duplication at the #include statement and so doesn't have to re-read the file.
Con: Most compilers use the include file's path to do this, so
#include "../include/foo.h"
#include "foo.h"
might both reference the same file but on some compilers will still produce duplication.
#ifndef guard
At the start of the .h file check for the definition of a unique pre-processor symbol and, if not defined, define it
#ifndef PAILLIER_H
#define PAILLIER_H
and at the very end of the file
#endif // PAILLIER_H (comment is optional)
Pro: De-duplicates regardless of path.
Con: Can cause problems if your guard name isn't unique enough (I worked on a project where someone used 'HEADER' in more than one header file)
Con: The pre-processor still has to read the entire header file to find the #endif.
In summary
You may also want to add the following to make your file work when included from both C and C++
#ifdef __cplusplus
extern "C" {
#endif
// all your symbols etc here
#ifdef __cplusplus
}; // extern "C"
#endif
This is going to make your header file look something like this:
#ifndef PAILLIER_H
#define PAILLIER_H
#ifdef __cplusplus
extern "C" {
#endif
// original code here
...
// end original code
#ifdef __cplusplus
}; // extern "C"
#endif
#endif // PAILLIER_H
or
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// original code here
...
// end original code
#ifdef __cplusplus
}; // extern "C"
#endif
--- Edit ---
There's no reason you can't use both
#pragma once
#ifndef MYPROJECT_SOMETHING_H
...
#endif
This way if #pragma fails you for path reasons, you're still covered.
I have one file example1.cpp with the main function. This file must have #include mylib.h and #include lib.h. File mylib.h also has #include lib.h. When I try to compile this program, the error redefinition xyz function ocurs.
example1.cpp
#include mylib.h
#include lib.h
int main(){
//code
}
mylib.h
#include lib.h
//rest code
You need to put include guards in your header file to prevent it from getting included multiple times during compilation.
#ifndef LIB_H
#define LIB_H
// Actual header file code
#endif
You have to wrap the .h files in #defines to avoid the redifinitions. For example:
#if !defined(_MY_LIB_H_)
#define _MY_LIB_H_
// Add your function definitions here...
#endif // _MY_LIB_H_
You can now include it anywhere and the function definition will be read once. Also note that you can use #ifndef depending on the compiler. VC++ for example, allows "#pragma once" if it's version 10 or higher:
#if _MSC_VER > 1000
#pragma once
#endif
In this case, you don't need to use the #defines explained above.