In an embedded system define:
#define Row1_PORT GPIOD
#define Row1_PIN GPIO_PIN_4
#define Row2_PORT GPIOD
#define Row2_PIN GPIO_PIN_7
#define Row3_PORT GPIOD
#define Row3_PIN GPIO_PIN_1
#define Row4_PORT GPIOD
#define Row4_PIN GPIO_PIN_3
//------------
#define Paste2(a,b) a ## b
#define Paste(a,b) Paste2(a,b)
#define NRows 4
I want use above defined macros in a loop like this:
for(i=1;i<=NRows;i++)
{
GPIO_Init(Paste(Paste(Row,i),_PORT),Paste(Paste(Row,i),_PIN),GPIO_MODE_IN_PU_NO_IT);
}
instead of
GPIO_Init(Row1_PORT,Row1_PIN);
GPIO_Init(Row2_PORT,Row2_PIN);
GPIO_Init(Row3_PORT,Row3_PIN);
GPIO_Init(Row4_PORT,Row4_PIN);
Is it possible?
I need some things like __COUNTER__ in ANSI C or C++. My compiler is IAR.
The preprocessor runs at compile time and textually modifies the source code presented to the compiler. What you are seeking to do is not possible; the compiler would embed the letter i into the macro expansions, not the value of the variable i at run-time.
I would probably use something like:
static const int ports[] = { 0, Row1_PORT, Row2_PORT, Row3_PORT, Row4_PORT };
static const int pins[] = { 0, Row1_PIN, Row2_PIN, Row3_PIN, Row4_PIN };
for (int i = 1; i <= NRows; i++)
GPIO_Init(ports[i], pins[i]);
Or I'd write it out longhand (as you show in your 'instead of' option) — there is little penalty and possibly a small saving for just 4 entries. If you have 100 ports to initialize, the loop would be better, of course.
Also, if you're going to use the port and pin numbers again in future (in other portions of the code than just the initialization code), having the arrays available will allow for greater flexibility.
As chris said -- this information isn't available to you during preprocessing, so you're ending up with
GPIO_Init(Rowi_PORT,Rowi_PIN);
which errors, as expected.
I don't think that macros are the right tool for this. Why not save your ports and pins in an array? Something like:
int ports[] = {Row1_PORT, Row2_PORT, ...};
int pins[] = {Row1_PIN, Row2_PIN, ...};
for (int i = 0; i < NRows; i++) {
GPIO_Init(ports[i], pins[i];
}
No less concise, but no macro hacks.
Related
A macro with a ## will concatenate the two elements together, for example if you use #define sptember oct ## ober you will obtain october.
So my problem is:
I have a macro like this #define getRegByPin(pin) set ## pin than I have from 1 to 19 some defines like this: #define set0 xxx and #define set1 xxx, etc.
But when I call my macro in code
int p = getPinNo(pin); st(getRegByPin(p), p, to); it replaces getRegByPin(p) with setp instead of set0 or set13 or etc.
What can i do?
Thx for help! You are awesome! :)
The C preprocessor (and C++ has just inherited it), just does textual substitution. It knows nothing of variables. So given
#define getRegByPin(pin) set ## pin
const int p = 5;
getRegByPin(p); // Will expand to setp, not set5
From the syntax, I guess that set0 to set13 are constants. Do they have values you can calculate? For example:
auto getRegByPin(int pin) { return set0+pin; } // or (set0 << pin)
If not, you are going to need a constant array which you can index:
auto getRegByPin(int pin) {
static const setType_t pins[16] = { set0, set1, set2 ... set15};
return pins[pin];
}
If they are not constants, but functions, your array will need to be an array of function pointers.
Prefer to use functions than the preprocessor.
When working on a large legacy code base, I today suspected a duplicate definition, but the dependency was not obvious to me human since it depended on a lots of compile-time calculations.
enum { MAX_ITEMS = 4 }; // defined somewhere in my code universe
enum { ITEMS_MAX = COMPLICATED_CALCULATIONS }; // somewhere else
I remembered some cases with analogous sizeof questions, when I let the compiler speak.
I usually put some ad-hoc formulations like this in the code (in the IDE), then I press [Alt]+[F9]:
void check() {
char bla[MAX_ITEMS == ITEMS_MAX]; // compiler-error shows difference
// ...but it causes a compiler warning about bla being never used
}
...and that's only because my compiler (Borland C++ 5.6.4) lazy evaluates the typedef for arrays with non-literal dimension:
typedef char bla[0]; // immediate compiler error
typedef char bla[0 != 0]; // obvious, but no compiler error HERE
Is there a really easy-to-memorize way for checks like this? And, please don't blame an old brave compiler ;-)
This works:
#define STATIC_ASSERT(x) typedef char foo[(x) ? 1 : -1];
I actually use the following setup borrowed from Boost, the purpose of this is to give each foo its own line number (otherwise a multiple definition error can happen):
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2( X, Y ) X##Y
#define STATIC_ASSERT(x) \
typedef char BOOST_JOIN(violation_on_line_,__LINE__) [(x) ? 1 : -1];
You should try if BOOST_STATIC_ASSERT works on your compiler.
Let's say that I need to create a LUT containing precomputed bit count values (count of 1 bits in a number) for 0...255 values:
int CB_LUT[256] = {0, 1, 1, 2, ... 7, 8};
If I don't want to use hard-coded values, I can use nice template solution How to count the number of set bits in a 32-bit integer?
template <int BITS>
int CountBits(int val)
{
return (val & 0x1) + CountBits<BITS-1>(val >> 1);
}
template<>
int CountBits<1>(int val)
{
return val & 0x1;
}
int CB_LUT[256] = {CountBits<8>(0), CountBits<8>(1) ... CountBits<8>(255)};
This array is computed completely at compile time. Is there any way to avoid a long list, and generate such array using some kind of templates or even macros (sorry!), something like:
Generate(CB_LUT, 0, 255); // array declaration
...
cout << CB_LUT[255]; // should print 8
Notes. This question is not about counting 1 bits in an number, it is used just as example. I want to generate such array completely in the code, without using external code generators. Array must be generated at compile time.
Edit.
To overcome compiler limits, I found the following solution, based on
Bartek Banachewicz` code:
#define MACRO(z,n,text) CountBits<8>(n)
int CB_LUT[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
#define MACRO(z,n,text) CountBits<8>(n+128)
int CB_LUT2[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
for(int i = 0; i < 256; ++i) // use only CB_LUT
{
cout << CB_LUT[i] << endl;
}
I know that this is possibly UB...
It would be fairly easy with macros using (recently re-discovered by me for my code) Boost.Preprocessor - I am not sure if it falls under "without using external code generators".
PP_ENUM version
Thanks to #TemplateRex for BOOST_PP_ENUM, as I said, I am not very experienced at PP yet :)
#include <boost/preprocessor/repetition/enum.hpp>
// with ENUM we don't need a comma at the end
#define MACRO(z,n,text) CountBits<8>(n)
int CB_LUT[256] = {
BOOST_PP_ENUM(256, MACRO, _)
};
#undef MACRO
The main difference with PP_ENUM is that it automatically adds the comma after each element and strips the last one.
PP_REPEAT version
#include <boost/preprocessor/repetition/repeat.hpp>
#define MACRO(z,n,data) CountBits<8>(n),
int CB_LUT[256] = {
BOOST_PP_REPEAT(256, MACRO, _)
};
#undef MACRO
Remarks
It's actually very straightforward and easy to use, though it's up to you to decide if you will accept macros. I've personally struggled a lot with Boost.MPL and template techniques, to find PP solutions easy to read, short and powerful, especially for enumerations like those. Additional important advantage of PP over TMP is the compilation time.
As for the comma at the end, all reasonable compilers should support it, but in case yours doesn't, simply change the number of repetitions to 255 and add last case by hand.
You might also want to rename MACRO to something meaningful to avoid possible redefinitions.
I like to do it like this:
#define MYLIB_PP_COUNT_BITS(z, i, data) \
CountBits< 8 >(i)
int CB_LUT[] = {
BOOST_PP_ENUM(256, MYLIB_PP_COUNT_BITS, ~)
};
#undef MYLIB_PP_COUNT_BITS
The difference with BOOST_PP_REPEAT is that BOOST_PP_ENUM generates a comma-separated sequence of values, so no need to worry about comma's and last-case behavior.
Furthermore, it is recommended to make your macros really loud and obnoixous by using a NAMESPACE_PP_FUNCTION naming scheme.
a small configuration thing is to omit the [256] in favor of [] in the array size so that you can more easily modify it later.
Finally, I would recommend making your CountBit function template constexpr so that you also can initialize const arrays.
Is there a more human-readable way for representing big numbers in the source code of an application written in C++ or C?
let's for example take the number 2,345,879,444,641 , in C or C++ if we wanted a program to return this number we would do return 2345879444641.
But this is not really readable.
In PAWN (a scripting language) for example I can do return 2_345_879_444_641 or even return 2_34_58_79_44_46_41 and these both would return the number 2,345,879,444,641.
This is much more readable for the human-eye.
Is there a C or C++ equivalent for this?
With a current compiler (C++14 or newer), you can use apostrophes, like:
auto a = 1'234'567;
If you're still stuck with C++11, you could use a user-defined literal to support something like: int i = "1_000_000"_i. The code would look something like this:
#include <iostream>
#include <string>
#include <cstdlib>
int operator "" _i (char const *in, size_t len) {
std::string input(in, len);
int pos;
while (std::string::npos != (pos=input.find_first_of("_,")))
input.erase(pos, 1);
return std::strtol(input.c_str(), NULL, 10);
}
int main() {
std::cout << "1_000_000_000"_i;
}
As I've written it, this supports underscores or commas interchangeably, so you could use one or the other, or both. For example, "1,000_000" would turn out as 1000000.
Of course, Europeans would probably prefer "." instead of "," -- if so, feel free to modify as you see fit.
With Boost.PP:
#define NUM(...) \
NUM_SEQ(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
#define NUM_SEQ(seq) \
BOOST_PP_SEQ_FOLD_LEFT(NUM_FOLD, BOOST_PP_SEQ_HEAD(seq), BOOST_PP_SEQ_TAIL(seq))
#define NUM_FOLD(_, acc, x) \
BOOST_PP_CAT(acc, x)
Usage:
NUM(123, 456, 789) // Expands to 123456789
Demo.
Another way is making an UDL. Left as an exercise (and also because it requires more code).
Here's a macro that would do it, tested on both MSVC and GCC. No reliance on Boost...
#define NUM(...) NUM_(__VA_ARGS__, , , , , , , , , , )
#define NUM_(...) NUM_MSVCHACK((__VA_ARGS__))
#define NUM_MSVCHACK(numlist_) NUM__ numlist_
#define NUM__(a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, ...) a1_##a2_##a3_##a4_##a5_##a6_##a7_##a8_
Use it like:
int y = NUM(1,2,3,4,5,6,7,8);
int x = NUM(100,460,694);
Produces:
int y = 12345678;
int x = 100460694;
For C++1y you can now use single quote(') as a digit separator. Based on N3781: Single-Quotation-Mark as a Digit Separator which has finally been accepted. Both gcc and clang have supported this feature as part of their C++1y implementation.
So the following program (see it live for clang):
#include <iostream>
int main(){
std::cout << 2'345'879'444'641 << std::endl ;
}
will output:
2345879444641
You could use a preprocessor macro
#define BILLION (1000*1000*1000)
then code e.g. (4*BILLION) ; if you care about large power of two just ust 1<<30
PS Notice that 1e6 is a double literal (same as 1.0e6)
And you could also:
patch the GCC lexer to accept 1_234_567 notation for number literals and publish that patch for conformance with GPLv3 and free software spirit.
probably in file libpp/lex.c and/or gcc/c-family/c-lex.c and/or gcc/cpp/lex.c of future GCC 4.8, i.e. current trunk.
lobby the C & C++ standardization groups to get that accepted in future C or C++ standards.
Suppose I have a macro defined as this:
#define FOO(x,y) \
do {
int a,b;
a = f(x);
b = g(x);
y = a+b;
} while (0)
When expanding the macro, does GCC "guarantee" any sort of uniqueness to a,b? I mean in the sense that if I use FOO in the following manner:
int a = 1, b = 2;
FOO(a,b);
After, preprocessing this will be:
int a = 1, b = 2;
do {
int a,b;
a = f(a);
b = g(b);
b = a+b;
} while (0)
Can/will the compiler distinguish between the a outside the do{} and the a inside the do? What tricks can I use to guarantee any sort of uniqueness (besides making the variables inside have a garbled name that makes it unlikely that someone else will use the same name)?
(Ideally functions would be more useful for this, but my particular circumstance doesn't permit that)
If we consider scoping of variables, it is guaranteed that a,b inside the do..while() will be different from the ones defined outside.
For your case, the a,b defined outside will not exist inside the do..while().
There are lots of things to watch out for when using MACROs.
Macros perform just string substitution. The semantic is low and the the compiler have a limited knowledge of the preprocessor (essentially #pragma which in fact is not a preprocessor keyword, and source line info).
In your case a and b are not initialized local value. Behavior is unpredictible.
Your expanded code is equivalent to the following one.
int a = 1, b = 2;
do {
int a___,b___;
a___ = f(a___);
b___ = g(b___);
b___ = a___+b___;
} while (0)
To avoid such case in c++ prefer the use of inline function or template.
If you use a c 1999 compliant compiler, you can use inline in c language.
http://en.wikipedia.org/wiki/Inline_function
In c you can make safer macro by defining longer variable and surrounding parameter by () :
#define FOO(x,y) \
do {
int FOO__a,FOO__b;
FOO__a = f(x);
FOO__b = g(x);
y = FOO__a+FOO__b + (y)*(y);
} while (0)
Note : I changed your example by adding a (y)*(y) to illustrate the case
It is also a good practice to use only once macro parameter.
This prevent side effects like that:
#define max(a,b) a>b?a:b
max(i++,--y)
Max will not return what you want.
Variables a and b are treated just as any local variables inside a local scope.
The C language guarantees that if those variables happen to have the same names as outer scope variables, the local variables will be the ones updated.
Here is an example to illustrate:
#include <stdio.h>
#define FOO(x) \
{ \
int a; \
a = x; \
printf("%d\n", a); \
}
int main()
{
int a = 1;
{
int a = 2;
printf("%d\n", a); // 2
FOO(3); // 3
printf("%d\n", a); // 2
}
printf("%d\n", a); // 1
getchar();
}
Now, of course it might be a bright idea to not name every single variable in your program "a" just because C guarantees that local variables take precedence. But technically there is nothing stopping you from it.
Btw MISRA-C bans naming like this, it require each variable no matter scope to have an unique name, for readability and maintenance reasons.
(As a sidenote, function-like macros is incredibly poor programming style and shouldn't be used. Use real functions instead, and inline them if performance is critical.)
There is no tricks other than garbling. The C and C++ preprocessors do not have the equivalent of lisp gensym or hygienic macros.
Nope, there is no guarantee of uniqueness.
Infact, your code is about to fail.
Macros are just like replacement of text.
I usually use crazy variable names if I am inside a macro, like this:
#define FOO(x,y) \
do {
int FOO_MACRO_a, FOO_MACRO_b;
FOO_MACRO_a = f(x);
FOO_MACRO_b = g(x);
y = FOO_MACRO_a + FOO_MACRO_b;
} while (0)
If you are targeting gcc and/or g++ then you can use their special macro block feature:
#define max(x, y) ({ typeof(x) a_ = (x); \
typeof(y) b_ = (y); \
(a_ > b_) ? a_ : b_ })
This allows you to create unique local variables, very much the same as writing a function.
Of course, for portability, it's not recommended. On the other hand, if you only plan to work on systems that offer gcc/g++, it will work on all of those.
Source: http://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_3.html#SEC30
Further, with gcc / g++ you can use the -Wshadow command line option. In the event you inadvertently reuse a local variable with the same name, it will warn you. You can further use -Werror to transform those warnings in error. Now you can't compile if there is the possibility of a mixed up variable. You need to make sure to use a block, though. A do/while() as others have presented would do the job.
int a;
// code from macro;
do { int a = 5; ... } while(false);
With the combo I just described (-Wshadow + -Werror), you get an error when you do int a = 5.
You can actually make sure that regardless of what x and y are you won't have this problem by doing the following:
#define FOO(x,y) \
do\
{\
int x##y##a,x##y##b;\
x##y##a = f(x);\
x##y##b = g(x);\
y = x##y##a + x##y##b;\
} while (0)
By making sure a and b names contains x and y names you know they are different. But that's a really bad code and you probably shouldn't code like this.
Macros are textually expanded as is, modulo parameter replacement, so there's nothing the compiler can do to provide the sort of guarantee you're asking for -- as you can see in the expansion, the a parameter will refer to the inner a, not the outer one. The solution is indeed to use "garbled" names, e.g. int FOO_a, FOO_b;
In your macro that is indeed a danger and so is the possible reuse of x which is not guaranteed to be an l-value and could change by being used in the macro twice.
Even if you do need a macro, it can still be a light wrapper around an inline function, and one such that will take x and give you both f(x) and g(x) without possibly having to re-evaluate x would certainly be safe.
In your case something like:
template< typename T >
struct Foo
{
T& x;
explicit Foo(T&x_) : x(x_)
{
}
int f();
int g();
};
template<typename T>
Foo<T> makeFoo(T& x)
{
return Foo<T>(x);
}
#define FOO(x,y)
{
Foo FOO_VAR(x);
y = FOO_VAR.f() + FOO_VAR.g();
}
would be a safer way to do things. Of course if you don't need the macro at all, do away with it.