I have read several articles about how Preprocessor directives work in C++.
It's clear to me that Preprocessor directives are managed by the pre-processor before compilation phase.
Let's consider this code:
#include <iostream>
#ifndef N
#define N 10
#endif
int main(){
int v[N];
return 0;
}
The Pre-processor will elaborate the source code by performing text replacement, so this code during compilation phase would be equivalent to:
int main(){
int v[10];
return 0;
}
Now my question is: Can I define a Macro by setting its value equal to a function?
It looks a bit weird to me but the answer is yes.
#include<iostream>
#include <limits>
#ifndef INT_MIN
#define INT_MIN std::numeric_limits<int>::min()
#endif
int get_max(){
return 5;
}
#ifndef INT_MAX
#define INT_MAX get_max()
#endif
int main()
{
std::cout << INT_MIN << " " << INT_MAX;
return 0;
}
Conceptually I'm not understanding why this code works, the pre-processor have to replace text before compilation phase, so how could a function be invoked (In this case get_max() function) ?
Functions invoking is a task managed by compiler? isn't it?
How could Pre-processor get access to std::numeric_limits::min()? This value is present inside the "limits" library, but if I understand correctly the libraries's inclusion is done by compiler.
For the sake of illustration I removed the includes from your code:
#ifndef INT_MIN
#define INT_MIN 0
#endif
int get_max(){
return 5;
}
#ifndef INT_MAX
#define INT_MAX get_max()
#endif
int main()
{
return INT_MIN + INT_MAX;
}
Then I invoked gcc with -E to see the output after preprocessing:
int get_max(){
return 5;
}
int main()
{
return 0 + get_max();
}
This is the code that will get compiled. The preprocessor does not call the funciton. It merely replaces INT_MAX with get_max().
Live Demo
Can I define a Macro by setting its value equal to a function?
Thats not what you do. #define INT_MAX get_max() just tells the preprocessor to replace INT_MAX with get_max(). The preprocessor doen't know nor care if get_max() is a function call or something else.
Related
I have a project where there are two different preprocessor macros with the same name, defined in two different include files (from two different libraries), and I have to check if they have the same value at build time.
So far I could make this check at run time, assigning the macro values to different variables in different implementation files, each including only one of the headers involved.
How can I do it at build time?
This is what I tried so far (where Macro1.h and Macro2.h are third-party files I cannot modify):
Header files:
TestMultiMacros.h:
#ifndef TEST_MULTI_MACROS_H
#define TEST_MULTI_MACROS_H
struct Values
{
static const unsigned int val1, val2;
static const unsigned int c1 = 123, c2 = 123;
};
#endif // TEST_MULTI_MACROS_H
Macro1.h:
#ifndef MACRO1_H
#define MACRO1_H
#define MY_MACRO 123
#endif // MACRO1_H
Macro2.h:
#ifndef MACRO2_H
#define MACRO2_H
#define MY_MACRO 123
#endif // MACRO2_H
Implementation files:
TestMultiMacros1.cpp:
#include "TestMultiMacros.h"
#include "Macro1.h"
const unsigned int Values::val1 = MY_MACRO;
TestMultiMacros2.cpp:
#include "TestMultiMacros.h"
#include "Macro2.h"
const unsigned int Values::val2 = MY_MACRO;
entrypoint.cpp:
#include "TestMultiMacros.h"
using namespace std;
static_assert(Values::val1 == Values::val2, "OK"); // error: expression did not evaluate to a constant
static_assert(Values::c1 == Values::c2, "OK");
int main()
{
}
I would be interested in a solution using both C++11 and C++17.
Include the first header. Then save the value of the macro to a constexpr variable:
constexpr auto foo = MY_MACRO;
Then include the second header. It should silently override MY_MACRO. If your compiler starts complaining, do #undef MY_MACRO first.
Then compare the new value of the macro with the variable using a static_assert:
static_assert(foo == MY_MACRO, "whatever");
Here's a very simple C++17 test which works with arbitrary (non-function) macros by comparing the text of the macro expansion. For c++11, which lacks the constexpr comparison in std::string_view, you can write it yourself in a couple of lines, as shown in this answer.
#include <string_view>
#define STRINGIFY(x) STRINGIFY_(x)
#define STRINGIFY_(x) #x
#include "macro1.h"
//#define MY_MACRO A night to remember
constexpr const char* a = STRINGIFY(MY_MACRO);
#undef MY_MACRO
#include "macro2.h"
//#define MY_MACRO A knight to remember
constexpr const char* b = STRINGIFY(MY_MACRO);
static_assert(std::string_view(a) == b, "Macros differ");
int main() { }
(Godbolt: https://godbolt.org/z/nH5qVo)
Of course, this depends on what exactly you mean by equality of macros. This version will report failure if one header file has
#define MY_MACRO (2+2)
and the other has
#define MY_MACRO 4
Also worth noting that stringification normalises whitespace but it does not normalise the presence of whitespace other than trimming the ends. So (2 + 2) and (2 + 2) will compare as equal, but not (2+2) and ( 2 + 2 )
I'm writing a bunch of related preprocessor macros, one of which generates labels which the other one jumps to. I use them in this fashion:
MAKE_FUNNY_JUMPING_LOOP(
MAKE_LABEL();
MAKE_LABEL();
)
I need some way to generate unique labels, one for each inner MAKE_LABEL call, with the preprocessor. I've tried using __LINE__, but since I call MAKE_LABEL inside another macro, they all have the same line and the labels collide.
What I'd like this to expand to is something like:
MAKE_FUNNY_JUMPING_LOOP(
my_cool_label_1: // from first inner macro
...
my_cool_label_2: // from second inner macro
...
)
Is there a way to generate hashes or auto-incrementing integers with the preprocessor?
If you're using GCC or MSVC, there is __COUNTER__.
Other than that, you could do something vomit-worthy, like:
#ifndef USED_1
#define USED_1
1
#else
#ifndef USED_2
#define USED_2
2
/* many many more */
#endif
#endif
I use this:
#define MERGE_(a,b) a##b
#define LABEL_(a) MERGE_(unique_name_, a)
#define UNIQUE_NAME LABEL_(__LINE__)
int main()
{
int UNIQUE_NAME = 1;
return 0;
}
... and get the following:
int main()
{
int unique_name_8 = 1;
return 0;
}
As others noted, __COUNTER__ is the easy but nonstandard way of doing this.
If you need extra portability, or for other cool preprocessor tricks, the Boost Preprocessor library (which works for C as well as C++) will work. For example, the following header file will output a unique label wherever it's included.
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/slot/slot.hpp>
#if !defined(UNIQUE_LABEL)
#define UNIQUE_LABEL
#define BOOST_PP_VALUE 1
#include BOOST_PP_ASSIGN_SLOT(1)
#undef BOOST_PP_VALUE
#else
#define BOOST_PP_VALUE BOOST_PP_INC(BOOST_PP_SLOT(1))
#include BOOST_PP_ASSIGN_SLOT(1)
#undef BOOST_PP_VALUE
#endif
BOOST_PP_CAT(my_cool_label_, BOOST_PP_SLOT(1)):
Sample:
int main(int argc, char *argv[]) {
#include "unique_label.h"
printf("%x\n", 1234);
#include "unique_label.h"
printf("%x\n", 1234);
#include "unique_label.h"
return 0;
}
preprocesses to
int main(int argc, char *argv[]) {
my_cool_label_1:
printf("%x\n", 1234);
my_cool_label_2:
printf("%x\n", 1234);
my_cool_label_3:
return 0;
}
I can't think of a way to automatically generate them but you could pass a parameter to MAKE_LABEL:
#define MAKE_LABEL(n) my_cool_label_##n:
Then...
MAKE_FUNNY_JUMPING_LOOP(
MAKE_LABEL(0);
MAKE_LABEL(1);
)
You could do this:
#define MAKE_LABEL() \
do { \
my_cool_label: \
/* some stuff */; \
goto my_cool_label; \
/* other stuff */; \
} while (0)
This keeps the scope of the label local, allowing any number of them inside the primary macro.
If you want the labels to be accessed more globally, it's not clear how your macro "MAKE_FUNNY_JUMPING_LOOP" references these labels. Can you explain?
It doesn't seem possible with a standard preprocessor, although you could fake it out by putting parameters within MAKE_LABEL or MAKE_FUNNY_JUMPING_LOOP, and use token pasting to create the label.
There's nothing preventing you from making your own preprocessing script that does the automatic increment for you. However, it won't be a standard C/C++ file in that case.
A list of commands available: http://www.cppreference.com/wiki/preprocessor/start
I wrote this simple program
#include <time.h>
int main()
{
#if ((clock_t)1000)
int x = 10;
#endif
return 0;
}
On compilation, I see the following error:
Error C1012 unmatched parenthesis: missing ')'
Why am I getting this error?
Changing the line from:
#if ((clock_t)1000)
to:
#if (clock_t)1000
resolves the compilation error.
But I can't do that, since ((clock_t)1000) is defined as a macro using the #define directive in the limits.h header file as :
#define CLOCKS_PER_SEC ((clock_t)1000)
and I need to use that directly.
EDIT:
Please pardon me for framing the question in such an unclear way.
Reframing my question now:
I have the following code:
#include <time.h>
#define DUMMY_CLOCKS_PER_SEC ((clock_t)1000)
int main()
{
#if CLOCKS_PER_SEC != DUMMY_CLOCKS_PER_SEC
#error "out of sync"
#endif
return 0;
}
But this gives the compilation error:
Error C1012 unmatched parenthesis: missing ')'
The preprocessor doesn't know anything about C++ datatypes, and doesn't understand cast expressions. It's used for simple text processing, and == and != can only compare single tokens.
Do the comparison in C++, not the preprocessor.
static_assert(CLOCKS_PER_SEC == DUMMY_CLOCKS_PER_SEC, "out of sync");
int main() {
return 0;
}
Don't worry about the runtime performance overhead. Since both macros expand to literals, the compiler will optimize it away.
You are confusing a preprocessor macro definition (CLOCKS_PER_SEC) with its expansion (that is implementation defined, and in your case seems to be ((clock_t)1000)).
It's not very clear what you want to do in your code.
If you want to check if this macro is defined, you can use the preprocessor #ifdef, e.g.:
#ifdef CLOCKS_PER_SEC
// your code
#endif
Anyway, this CLOCKS_PER_SEC macro is defined by the standard, so it should be always defined in a standard-compliant time.h library implementation.
If you have something different in your mind, please clarify your goal.
EDIT Based on your clarifying comment below, you may want to use an if to compare the values (expansions) of these two macros:
if (DUMMY_CLOCKS_PER_SEC != CLOCKS_PER_SEC) {
...
} else {
...
}
((clock_t)1000) is defined as a macro using the #define directive in the limits.h header file as :
#define CLOCKS_PER_SEC ((clock_t)1000)
The file does not define a macro named ((clock_t)1000). It defines a macro named CLOCKS_PER_SEC. ((clock_t)1000) is the value of the macro.
((clock_t)1000) is not a macro and is something that cannot be used in an #if directive.
Thanks for all the responses everyone.
Another solution I figured out for this problem is to use constexpr specifier which is a feature of c++11. ConstExpr allows us to evaluate the value of a variable or a function at compile time.
Changing the code from:
#if CLOCKS_PER_SEC != DUMMY_CLOCKS_PER_SEC
#error "out of sync"
#endif
to the following resolves the issue:
constexpr int DUMMY_CLOCK_NOT_EQUAL = (DUMMY_CLOCKS_PER_SEC != CLOCKS_PER_SEC) ? 1 : 0;
#if DUMMY_CLOCK_NOT_EQUAL
#error "out of sync"
#endif
Is it possible to disable chunks of code with c/c++ preprocessor depending on some definition, without instrumenting code with #ifdef #endif?
// if ENABLE_TEST_SONAR is not defined, test code will be eliminated by preprocessor
TEST_BEGIN(SONAR)
uint8_t sonar_range = get_sonar_measurement(i);
TEST_ASSERT(sonar_range < 300)
TEST_ASSERT(sonar_range > 100)
TEST_END
Functionally equivalent to something as follows:
#ifdef TEST_SONAR
serial_print("test_case sonar:\r\n");
uint8_t sonar_range = get_sonar_measurement(i);
serial_print(" test sonar_range < 300:%d\r\n", sonar_range < 300);
serial_print(" test sonar_range > 100:%d\r\n", sonar_range > 100);
#endif TEST_SONAR
Multiple lines can be disabled only with #ifdef or #if but single lines can be disabled with a macro. Note that multiple lines can be combined with \
#ifdef DOIT
#define MYMACRO(x) \
some code \
more code \
even more \
#else
#define MYMACRO(x)
#endif
Then when you call MYMACRO anplace that code will either be included or not based on whether DOIT is defined
That's the closest you can come and is used frequently for debugging code
EDIT: On a whim I tried the following and it seems to work (in MSVC++ and g++):
#define DOIT
#ifdef DOIT
#define MYMACRO(x) x
#else
#define MYMACRO(x)
#endif
void foo(int, int, int)
{
}
int main(int, char **)
{
int x = 7;
MYMACRO(
if (x)
return 27;
for (int i = 0; i < 10; ++i)
foo(1, 2, 3);
)
}
No, the only way to disable sections of codes effectively using preprocessing is by #ifdef #endif. Theoretically, you could use #if identifier, but it's better to stick to checking whether a variable is defined.
Another option (perhaps) is to use a preprocessing macro:
Edit:
Perhaps using plain functions and #ifdef might work better?
function test_function() {
/* Do whatever test */
}
#define TESTING_IDENTIFIER
#define TEST( i, f ) if ((i)) do { f } while (0)
Then, for each test, you define a unique identifier and call it by providing the identifier first and the function (with parenthesis) second.
TEST( TESTING_IDENTIFIER, test_function() );
Finally, f can be anything that's syntactically correct -- You don't have to create a function for every test, you can put the code inline.
I will anyway mention an obvious solution of
#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }
...
TEST_SONAR
code
TEST_SONAR_END
The code will still get compiled, not completely removed, but some smart compilers might optimize it out.
UPD: just tested and
#include <iostream>
using namespace std;
//#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }
int main() {
TEST_SONAR
cout << "abc" << endl;
TEST_SONAR_END
}
produces absolutely identical binaries with cout line commented out and non commented, so indeed the code is stripped. Using g++ 4.9.2 with -O2.
I think this is child question but i can't find info how to solve it.
//*.h:
class Foo
{
#if defined(RedefChallangesCount)
static const mainDataType ChallangesCount = 500;
#undef RedefChallangesCount
#else
static const mainDataType ChallangesCount = 1;
#endif
...
int _correctAnswers[ChallangesCount];
....
}
In my VS tests class:
#include "stdafx.h"
#include "CppUnitTest.h"
#define RedefChallangesCount
#include "..\Core\ChallengeManager.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace Brans;
namespace CoreTests
{
TEST_CLASS(SomeTestClass)
{
public:
TEST_METHOD(SomeTestMethod)
{
Foo* cm = new Foo();
cm->Method();
...
delete cm;
}
}
}
It seems for me that i do all like in docs, but when run test with #define RedefChallangesCount line i got strange errors like "Access violation reading location", sometimes bad array
_correctAnswers. At the same time i see that ChallangesCount is 500 as expected. If i comment #define RedefChallangesCount line - all errors gone...
What can be wrong?
Your #undef makes me suspicious that this header is being included elsewhere (e.g by ChallengeManager.cpp, meaning you'll end up with your _correctAnswers having a size of 500 in some places and 1 in others, which would certainly explain your crash.
(edit): Are your tests a separate project in the solution, with the main code in its own project, or is your code all compiled directly in the test project?
To be safe, set your #define in the VS build configuration (for all projects being linked into the tests - you'll need to add a Tests build config for this, and use it instead of Debug/Release for the test build) rather than defining it in code, and remove the #undef
I tend not to have if defined sections within code, especially class code. I would tend to use a variable, and branch based on its value:
in the test class remove the #define RedefChallangesCount and replace with a global variable of bool RedefChallangesCount
Then your code becomes much simpler and can be as follows (simplified version for demonstration purposes):
#include <iostream>
using namespace std;
bool RedefChallangesCount = false;
int main()
{
int ChallangesCount;
cout << RedefChallangesCount << endl;
if (RedefChallangesCount)
ChallangesCount = 500;
else
ChallangesCount = 1;
cout << ChallangesCount << endl;
return 0;
}
as opposed to:
#if defined(RedefChallangesCount)
static const mainDataType ChallangesCount = 500;
#undef RedefChallangesCount
#else
static const mainDataType ChallangesCount = 1;
#endif
However, let me know if using preprocessor is a requirement and then I can try and sort you out a solution using that methodology, though as I said, I don't use preprocessor directives for actual program flow (have to add normally, as guaranteed I have done it once for a valid reason, and cant remember).