When looking at c++ source code, I almost always see #define macros at the head of the file, this makes sense in most cases, and I can see why this is best practice, but I recently came upon a situation where it might be better to keep the preprocessor definitions in a function body.
I'm writing a quaternion class, and my code for the function in question looks like this:
Quaternion Quaternion::operator*(const Quaternion& q){
Quaternion resultQ;
// These are just macros to make the code easier to read,
// 1 denotes the quaternion on the LHS of *,
// 2 denotes the quaternion of the RHS 0f *, e.a. Q1 * Q2.
// the letter denotes the value of the real number constant part
// for each seperate part of the quaterion, e.a. (a+bi+cj+dk)
#define a1 this->get_real()
#define a2 q.get_real()
#define b1 this->get_i()
#define b2 q.get_i()
#define c1 this->get_j()
#define c2 q.get_j()
#define d1 this->get_k()
#define d2 q.get_k()
// This arithemtic is based off the Hamilton product
// (http://en.wikipedia.org/wiki/Quaternion#Hamilton_product)
resultQ.set_real(a1*a2 - b1*b2 - c1*c2 - d1*d2);
resultQ.set_i(a1*b2 + b1*a2 + c1*d2 - d1*c2);
resultQ.set_j(a1*c2 - b1*d2 + c1*a2 + d1*b2);
resultQ.set_k(a1*d2 + b1*c2 - c1*b2 + d1*a2);
return resultQ;
}
I decided to add in the #define because if I substituted in all the macros manually, each line would be too long, and either be cut off or carried over to the next line when read. I could have done the same thing with variables, but I decided that would be an unnecessary overhead, so I used #define because it has no runtime overhead. Is this an acceptable practice? Is there a better way to make what I am doing here readable?
Instead of
#define a1 this->get_real()
write
auto const a1 = get_real();
And just use different names for each value of a quantity that changes.
Yes there are cases where a local #define makes sense. No this is not such a case. In particular, since you've forgotten to #undef the macros they will almost certainly cause inadvertent text substitution in some other code, if this is in a header (as indicated).
By, the way, instead of
Quaternion Quaternion::operator*(const Quaternion& q){
I would write
Quaternion Quaternion::operator*(const Quaternion& q) const {
so that also const quaternions can be multiplied.
Macros don't respect scope. Those macros are defined for the rest of the file after they appear. If you have a variable a1 in the next function, it will mess up. You should #undef all the macros at the end of the function.
Better is to create some utility functions somehow. In C++11
auto a1 = [this](){ return this->get_real(); }
...
resultQ.set_real(a1()*a2() ...
Not quite the same as you need the () but maybe good enough for you.
If the values of a1 etc don't change during the calculations, you should use Alf's suggestion.
The other answers already give alternatives to macros. You should definitely follow one such alternative because this use of macros in your code is unnecessary and bad.
But I feel your code needs redesign anyway, after which you'll see that neither macros nor their alternatives are needed.
A quaternion is a generalization of a complex number, and as such, essentially it has a number of data members (four rather than two), a number of constructors, and a number of operators.
You might have a look at the design of std::complex to get ideas. The design of a quaternion need not be much different. In particular, why would you need setters/getters to access data from a member function? These methods are exactly what makes expressions long! (along with the unnecessary use of this).
So, if the data members of a quaternion are a, b, c, d, and if there is a constructor with these four values are arguments, then your operator* should really look like this:
Quaternion Quaternion::operator*(const Quaternion& q) const
{
return Quaternion{
a*q.a - b*q.b - c*q.c - d*q.d,
a*q.b + b*q.a + c*q.d - d*q.c,
a*q.c - b*q.d + c*q.a + d*q.b,
a*q.d + b*q.c - c*q.b + d*q.a
};
}
No need for macros, helper functions, or intermediate variables.
Related
I'm working on a dll that attaches to a program and reads some data from the target program. I do this by finding the struct address and casting that address to a pointer of the respective struct in my code.
Example:
class Structure {
char pad_1[0x30];
float val1;
float val2
char pad_2[0x20];
Structure* next;
}
Here if I find the address of the structure to be 0x1234 I can just do (Structure*)0x1234 and I have access to it, notice that there are some padding values, those values I simply don't know what they are or I don't need them.
I want to write this struct in my code (for maintainability purposes) as following:
class Structure {
Offset(0x30)
float val1;
float val2;
Offset(0x58) /// 0x30 + 2x floats + 0x20 padding
Structure* next;
}
This Offset macro should add padding automatically, basically with Offset(num) u specify the offset of the field in the class, this macro should add this padding automatically.
I have no idea if this is possible with C macros, right now I'm defining my models in YAML and using a python script to generate them, there are some disadvantages to this however...
It seems to me, that what you want to do is to essentially make the macros expand into char arrays of given size. The only tricky thing here is to have unique names of the structure members, and you can achieve that using __LINE__ and double-step concatenation in a macro:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define OFFSET(size) char TOKENPASTE2(pad_, __LINE__)[size]
and use it the way you wanted. Note, that you get some cryptic structure member names, that are not visible from code but might be visible in IDE during development. I'm not sure if it's really more maintainable, I would just put there char arrays manually.
Original answer from: Creating C macro with ## and __LINE__ (token concatenation with positioning macro)
Offset(0x58) /// 0x30 + 2x floats + 0x20 padding
It is not possible - you can't like "query" how much memory "was" used when still inside defining the type. The information is known after the type was defined. It is not possible in the C language.
This is not something you solve with macro's, or structs.
High level, you want a tuple<padding<30>, float, float, padding<58>, void*>. That's not a std::tuple, but the idea is similar - you want a class template that calculates the various offsets, using your own rules.
Is there a more concise way to write the second line of this function without repeating a reduntantly?
void myfunc()
{
bool a = false; // Assume that this won't alway be hardcoded to false.
a = !a;
}
Is there a more concise way to write the second line of this function without repeating a reduntantly?
! is an unary operator, you cannot associate it with = if this is what you expected.
But you can do something like a ^= true;, this is not a more concise way but this is without repeating a redundantly. Anyway this is not a good way to do contrarily to a = !a; which is much more readable
Well, I don't really see the value of doing so, but you could use xor or a simple decrement. Both of these work.
a ^= 1;
a--;
Then you won't have to repeat a.
But if you want it to be very clear, consider using a function:
void flip(bool *b)
{
(*b)--;
}
bool b = true;
flip(&b);
In C++, you can use references
void flip(bool &b)
{
b--;
}
bool b = true;
flip(b);
Or write a macro. Actually, macros are pretty handy for solving duplication problems. Although, I almost never use them for that, since it's simply rarely worth the effort. I wrote one macro to avoid duplication for malloc calls. Such a call typically look like this:
int *x = malloc(12 * sizeof *x);
You can avoid the duplication with this:
#define ALLOC(p, n) \
((p) = malloc((n) * sizeof *(p)))
But even this is something I hesitate to use.
To be honest, it's not really a problem worth solving. :)
The only possible answer is: unfortunately not.
The unary operator ! is actually concise enough, and any other trick would lead to unreadable code.
Any other shortcut form, for example for binary operators such as + or *:
a += 5;
b *= 7;
mantain the reference to the original meaning of theoperator: multiplication and addition respectively.
In your sentence:
without repeating a reduntantly
there's the wrong assumption that a is redundant in case the compiler could be instructed to negate a without repeating the variable name. No: it tells to people reading the code (even to yourself, for example an year later!) that the variable to be negated is a. And since C grammar doesn't define any syntactic sugar for logical negation operator, a is not redundant at all.
If have encountered this claim multiple times and can't figure out what it is supposed to mean. Since the resulting code is compiled using a regular C compiler it will end up being type checked just as much (or little) as any other code.
So why are macros not type safe? It seems to be one of the major reasons why they should be considered evil.
Consider the typical "max" macro, versus function:
#define MAX(a,b) a < b ? a : b
int max(int a, int b) {return a < b ? a : b;}
Here's what people mean when they say the macro is not type-safe in the way the function is:
If a caller of the function writes
char *foo = max("abc","def");
the compiler will warn.
Whereas, if a caller of the macro writes:
char *foo = MAX("abc", "def");
the preprocessor will replace that with:
char *foo = "abc" < "def" ? "abc" : "def";
which will compile with no problems, but almost certainly not give the result you wanted.
Additionally of course the side effects are different, consider the function case:
int x = 1, y = 2;
int a = max(x++,y++);
the max() function will operate on the original values of x and y and the post-increments will take effect after the function returns.
In the macro case:
int x = 1, y = 2;
int b = MAX(x++,y++);
that second line is preprocessed to give:
int b = x++ < y++ ? x++ : y++;
Again, no compiler warnings or errors but will not be the behaviour you expected.
Macros aren't type safe because they don't understand types.
You can't tell a macro to only take integers. The preprocessor recognises a macro usage and it replaces one sequence of tokens (the macro with its arguments) with another set of tokens. This is a powerful facility if used correctly, but it's easy to use incorrectly.
With a function you can define a function void f(int, int) and the compiler will flag if you try to use the return value of f or pass it strings.
With a macro - no chance. The only checks that get made are it is given the correct number of arguments. then it replaces the tokens appropriately and passes onto the compiler.
#define F(A, B)
will allow you to call F(1, 2), or F("A", 2) or F(1, (2, 3, 4)) or ...
You might get an error from the compiler, or you might not, if something within the macro requires some sort of type safety. But that's not down to the preprocessor.
You can get some very odd results when passing strings to macros that expect numbers, as the chances are you'll end up using string addresses as numbers without a squeak from the compiler.
Well they're not directly type-safe... I suppose in certain scenarios/usages you could argue they can be indirectly (i.e. resulting code) type-safe. But you could certainly create a macro intended for integers and pass it strings... the pre-processor handling the macros certainly doesn't care. The compiler may choke on it, depending on usage...
Since macros are handled by the preprocessor, and the preprocessor doesn't understand types, it will happily accept variables that are of the wrong type.
This is usually only a concern for function-like macros, and any type errors will often be caught by the compiler even if the preprocessor doesn't, but this isn't guaranteed.
An example
In the Windows API, if you wanted to show a balloon tip on an edit control, you'd use Edit_ShowBalloonTip. Edit_ShowBalloonTip is defined as taking two parameters: the handle to the edit control and a pointer to an EDITBALLOONTIP structure. However, Edit_ShowBalloonTip(hwnd, peditballoontip); is actually a macro that evaluates to
SendMessage(hwnd, EM_SHOWBALLOONTIP, 0, (LPARAM)(peditballoontip));
Since configuring controls is generally done by sending messages to them, Edit_ShowBalloonTip has to do a typecast in its implementation, but since it's a macro rather than an inline function, it can't do any type checking in its peditballoontip parameter.
A digression
Interestingly enough, sometimes C++ inline functions are a bit too type-safe. Consider the standard C MAX macro
#define MAX(a, b) ((a) > (b) ? (a) : (b))
and its C++ inline version
template<typename T>
inline T max(T a, T b) { return a > b ? a : b; }
MAX(1, 2u) will work as expected, but max(1, 2u) will not. (Since 1 and 2u are different types, max can't be instantiated on both of them.)
This isn't really an argument for using macros in most cases (they're still evil), but it's an interesting result of C and C++'s type safety.
There are situations where macros are even less type-safe than functions. E.g.
void printlog(int iter, double obj)
{
printf("%.3f at iteration %d\n", obj, iteration);
}
Calling this with the arguments reversed will cause truncation and erroneous results, but nothing dangerous. By contrast,
#define PRINTLOG(iter, obj) printf("%.3f at iteration %d\n", obj, iter)
causes undefined behavior. To be fair, GCC warns about the latter, but not about the former, but that's because it knows printf -- for other varargs functions, the results are potentially disastrous.
When the macro runs, it just does a text match through your source files. This is before any compilation, so it is not aware of the datatypes of anything it changes.
Macros aren't type safe, because they were never meant to be type safe.
The compiler does the type checking after macros had been expanded.
Macros and there expansion are meant as a helper to the ("lazy") author (in the sense of writer/reader) of C source code. That's all.
So I often see something like this:
#define gf_PI f32(3.14159265358979323846264338327950288419716939937510)
#define gf_PIhalf f32(3.14159265358979323846264338327950288419716939937510 * 0.5)
This means that half PI value is calculated every time I use gf_PIhalf in my code, right?
Wouldn't it be better to literally write the value of half PI instead?
Wouldn't it be even better to do the following:
#define gf_PI f32(3.14159265358979323846264338327950288419716939937510)
const float gf_PIHalf = gf_PI * 0.5f; // PIHalf is calculated once
Finally wouldn't it be best to do it like this (and why it doesn't seem to be a common practice):
const float gf_PI = 3.14159265358979323846264338327950288419716939937510;
const float gf_PIHalf = gf_PI * 0.5f;
This means that half PI value is calculated every time I use gf_PIhalf in my code, right?
Nope, not likely.
You can reasonably count on your compiler to do that multiplication at compile time, not runtime.
Your conclusions are somewhat right, except that the #define version will almost definitely resolve in compile time and the bit about types const globals being uncommon practice. They are common practice in modern good code. #defines are all but dead for this use. The best practice is to define your file scope globals in an unnamed namespace:
namespace
{
const float g_SomeGlobal = 123.456f;
}
This prevents anyone outside of your translation unit from being able to 'see' g_SomeGlobal.
I've recently (only on SO actually) run into uses of the C/C++ comma operator. From what I can tell, it creates a sequence point on the line between the left and right hand side operators so that you have a predictable (defined) order of evaluation.
I'm a little confused about why this would be provided in the language as it seems like a patch that can be applied to code that shouldn't work in the first place. I find it hard to imagine a place it could be used that wasn't overly complex (and in need of refactoring).
Can someone explain the purpose of this language feature and where it may be used in real code (within reason), if ever?
It can be useful in the condition of while() loops:
while (update_thing(&foo), foo != 0) {
/* ... */
}
This avoids having to duplicate the update_thing() line while still maintaining the exit condition within the while() controlling expression, where you expect to find it. It also plays nicely with continue;.
It's also useful in writing complex macros that evaluate to a value.
The comma operator just separates expressions, so you can do multiple things instead of just one where only a single expression is required. It lets you do things like
(x) (y)
for (int i = 0, j = 0; ...; ++i, ++j)
Note that x is not the comma operator but y is.
You really don't have to think about it. It has some more arcane uses, but I don't believe they're ever absolutely necessary, so they're just curiosities.
Within for loop constructs it can make sense. Though I generally find them harder to read in this instance.
It's also really handy for angering your coworkers and people on SO.
bool guess() {
return true, false;
}
Playing Devil's Advocate, it might be reasonable to reverse the question:
Is it good practice to always use the semi-colon terminator?
Some points:
Replacing most semi-colons with commas would immediately make the structure of most C and C++ code clearer, and would eliminate some common errors.
This is more in the flavor of functional programming as opposed to imperative.
Javascript's 'automatic semicolon insertion' is one of its controversial syntactic features.
Whether this practice would increase 'common errors' is unknown, because nobody does this.
But of course if you did do this, you would likely annoy your fellow programmers, and become a pariah on SO.
Edit: See AndreyT's excellent 2009 answer to Uses of C comma operator. And Joel 2008 also talks a bit about the two parallel syntactic categories in C#/C/C++.
As a simple example, the structure of while (foo) a, b, c; is clear, but while (foo) a; b; c; is misleading in the absence of indentation or braces, or both.
Edit #2: As AndreyT states:
[The] C language (as well as C++) is historically a mix of two completely different programming styles, which one can refer to as "statement programming" and "expression programming".
But his assertion that "in practice statement programming produces much more readable code" [emphasis added] is patently false. Using his example, in your opinion, which of the following two lines is more readable?
a = rand(), ++a, b = rand(), c = a + b / 2, d = a < c - 5 ? a : b;
a = rand(); ++a; b = rand(); c = a + b / 2; if (a < c - 5) d = a; else d = b;
Answer: They are both unreadable. It is the white space which gives the readability--hurray for Python!. The first is shorter. But the semi-colon version does have more pixels of black space, or green space if you have a Hazeltine terminal--which may be the real issue here?
Everyone is saying that it is often used in a for loop, and that's true. However, I find it's more useful in the condition statement of the for loop. For example:
for (int x; x=get_x(), x!=sentinel; )
{
// use x
}
Rewriting this without the comma operator would require doing at least one of a few things that I'm not entirely comfortable with, such as declaring x outside the scope where it's used, or special casing the first call to get_x().
I'm also plotting ways I can utilize it with C++11 constexpr functions, since I guess they can only consist of single statements.
I think the only common example is the for loop:
for (int i = 0, j = 3; i < 10 ; ++i, ++j)
As mentioned in the c-faq:
Once in a while, you find yourself in a situation in which C expects a
single expression, but you have two things you want to say. The most
common (and in fact the only common) example is in a for loop,
specifically the first and third controlling expressions.
The only reasonable use I can think of is in the for construct
for (int count=0, bit=1; count<10; count=count+1, bit=bit<<1)
{
...
}
as it allows increment of multiple variables at the same time, still keeping the for construct structure (easy to read and understand for a trained eye).
In other cases I agree it's sort of a bad hack...
I also use the comma operator to glue together related operations:
void superclass::insert(item i) {
add(i), numInQ++, numLeft--;
}
The comma operator is useful for putting sequence in places where you can't insert a block of code. As pointed out this is handy in writing compact and readable loops. Additionally, it is useful in macro definitions. The following macro increments the number of warnings and if a boolean variable is set will also show the warning.
#define WARN if (++nwarnings, show_warnings) std::cerr
So that you may write (example 1):
if (warning_condition)
WARN << "some warning message.\n";
The comma operator is effectively a poor mans lambda function.
Though posted a few months after C++11 was ratified, I don't see any answers here pertaining to constexpr functions. This answer to a not-entirely-related question references a discussion on the comma operator and its usefulness in constant expressions, where the new constexpr keyword was mentioned specifically.
While C++14 did relax some of the restrictions on constexpr functions, it's still useful to note that the comma operator can grant you predictably ordered operations within a constexpr function, such as (from the aforementioned discussion):
template<typename T>
constexpr T my_array<T>::at(size_type n)
{
return (n < size() || throw "n too large"), (*this)[n];
}
Or even something like:
constexpr MyConstexprObject& operator+=(int value)
{
return (m_value += value), *this;
}
Whether this is useful is entirely up to the implementation, but these are just two quick examples of how the comma operator might be applied in a constexpr function.