I want to replace a flow of transforming QString to char* in Qt4:
str.toLatin1().data()
to the same in Qt3:
str.latin()
using some construction as:
#define toLatin1().data() latin()
Is it really? Is there another way to do this?
I'd say the most maintainable solution would be to introduce a function for it:
inline const char* qstringToLatinChar(const QString &str)
{
#if Qt4
return str.toLatin1().data();
#else
return str.latin();
#endif
}
Such a function can quickly be substituted at existent code sites even with sed or the like. It has the added benefit of introducing a meaningful name for the operation.
Related
#define ELEMENT(TYPE, FIELD)\
bool get##FIELD(TYPE *field) const throw()\
{ \
return x_->get##FIELD(y_, field);\
} \
I never met code like this before.
First, why do we put code in #define, is it a macro? So, I can use ELEMENT() later in other places?
Second, what is ##? What I can find online is "The ## operator takes two separate tokens and pastes them together to form a single token. The resulting token could be a variable name, class name or any other identifier."
Could someone tell me how I should know what this kind of code works?
Yes, ELEMENT() is a preprocessor macro, which is just a fancy way to replace one piece of text with another piece of text before the compiler is invoked. At the site where a macro is invoked, it is replaced with the text content of the macro. If the macro has parameters, each parameter is replaced with the text that the caller passed in to the macro.
In this case, the TYPE parameter is being used as-is within the macro text, whereas the FIELD parameter is being concatenated with get via ## concatenation to produce a new token identifier get<FIELD>.
ELEMENT() can be used like this, for example:
class MyClass
{
ELEMENT(int, IntValue) // TYPE=int, FIELD=IntValue
ELEMENT(string, StrData) // TYPE=string, FIELD=StrData
// and so on ...
};
Which will be expanded by the preprocessor to this code, which is what the compiler actually sees:
class MyClass
{
bool getIntValue(int *field) const throw()
{
return x_->getIntValue(y_, field);
}
bool getStrData(string *field) const throw()
{
return x_->getStrData(y_, field);
}
// and so on ...
};
I'm sorry to tell you, someone tried to be clever.
#define is used to textually replace one piece of text with another. The 2 arguments can be passed as a kind of arguments. Normally, such an argument is a token. However, thanks to ##, one can do token concatenation.
Let's take an example: ELEMENT(int, Cost);
This will result in the following code being injected:
bool getCost(int *field) const throw()
...
So as you can see, int is kept as token, while Cost is glued together into getCost.
I hope you found this in legacy code, cause using the preprocessor is considered bad coding in C++. The language hasn't been able to get rid of most usages. However they are providing alternatives to most common usages.
The #include and header guards have gotten replacements with the C++20 modules proposal.
I develop a mac app using c++. I want to define the macro 'logi' corresponding to the call of two methods, so that method1() and method2() are being called. So I tried this:
#define logi method1 method2
It does not work. What is standard writing of this situation? thanks a lot!
At very first: If you can, avoid macros. If it is about calling two functions in a sequence, prefer defining an inline function instead:
inline void logi()
{
method1();
method2();
}
While inline just is a recommendation for the compiler – and it might choose not to do so – for such simple functions you won't find any compiler not following this recommendation (rather would the function be inlined even without keyword).
This approach is much safer – and anything you do wrong the compiler will show you right at the function definition.
If you insist on a macro: Best practice is letting it look like a function, if it behaves like such one, as in your case:
#define logi() do { method1(); method2(); } while(false)
The loop wrapping around makes this macro robust if used like a function somewhere in code, imagine it was used without like that:
if(someCondition)
logi();
Guess, method2 would get called unconditionally (well, another example showing why it's good practice always to place braces around branch and loop bodies...).
The colon is skipped deliberately, so the user is forced to place it, again making the macro behave like an ordinary function.
Be aware that for macros the pre-processor does nothing more than simple text replacement. So whatever you define, it must be valid C++ code (to be precise: the outcome, when the pre-processor is done, must be valid code). How would a macro look like, if you needed to pass arguments to your functions? Well, you need to include them in the macro definition, too:
#define logi(A1, A2, B1, B2, B3) do { method1(A1, A2); method2(B1, B2, B3) } while(false)
I guess you only forgot the ';' between the two functions. Therefore that the #define-macro only is a text-replacement in your code you need to 'end' the call of your function with a ';'.
But you might want to overthink using the #define-macro that way. It does not seem to make much sense to me to do it this way. See here on "when to use #define"
#include <iostream>
#define logi fun1(); fun2();
void fun1(void)
{
std::cout << "fun1 called\n";
}
void fun2(void)
{
std::cout << "fun2 called\n";
}
int main(void)
{
logi
return 0;
}
I was programming a manchester decoding algorithm for arduino, and I often had to print debug stuff when trying to get things working, but printing to serial and string constants add a lot of overhead. I can't just leave it there in the final binary.
I usually just go through the code removing anything debug related lines.
I'm looking for a way to easily turn it on and off.
The only way I know is this
#if VERBOSE==1
Serial.println();
Serial.print(s);
Serial.print(" ");
Serial.print(t);
Serial.print(" preamble");
#endif
...
#if VERBOSE==1
Serial.println(" SYNC!\n");
#endif
and on top of the file I can just have
#define VERBOSE 0 // 1 to debug
I don't like how much clutter it adds to single liners. I was very tempted to do something very nasty like this. But yeah, evil.
Change every debug output to
verbose("debug message");
then use
#define verbose(x) Serial.print(x) //debug on
or
#define verbose(x) //debug off
There's a C++ feature that allows me to just do this instead of preprocessor?
At the risk of sounding silly: Yes, there is a C++ feature for this, it looks like this:
if (DEBUG)
{
// Your debugging stuff here…
}
If DEBUG is a compile-time constant (I think using a macro is reasonable but not required in this case), the compiler will almost certainly generate no code (not even a branch) for the debugging stuff if debug is false at compile-time.
In my code, I like having several debugging levels. Then I can write things like this:
if (DEBUG_LEVEL >= DEBUG_LEVEL_FINE)
{
// Your debugging stuff here…
}
Again, the compiler will optimize away the entire construct if the condition is false at compile-time.
You can even get more fancy by allowing a two-fold debugging level. A maximum level enabled at compile-time and the actual level used at run-time.
if (MAX_DEBUG >= DEBUG_LEVEL_FINE && Config.getDebugLevel() >= DEBUG_LEVEL_FINE)
{
// Your debugging stuff here…
}
You can #define MAX_DEBUG to the highest level you want to be able to select at run-time. In an all-performance build, you can #define MAX_DEBUG 0 which will make the condition always false and not generate any code at all. (Of course, you cannot select debugging at run-time in this case.)
However, if squeezing out the last instruction is not the most important issue and all your debugging code does is some logging, then the usual pattern lokks like this:
class Logger
{
public:
enum class LoggingLevel { ERROR, WARNING, INFO, … };
void logError(const std::string&) const;
void logWarning(const std::string&) const;
void logInfo(const std::string&) const;
// …
private:
LoggingLevel level_;
};
The various functions then compare the current logging level to the level indicated by the function name and if it is less, immediately return. Except in tight loops, this will probably be the most convenient solution.
And finally, we can combine both worlds by providing inline wrappers for the Logger class.
class Logger
{
public:
enum class LoggingLevel { ERROR, WARNING, INFO, … };
void
logError(const char *const msg) const
{
if (COMPILE_TIME_LOGGING_LEVEL >= LoggingLevel::ERROR)
this->log_(LoggingLevel::ERROR, msg);
}
void
logError(const std::string& msg) const
{
if (COMPILE_TIME_LOGGING_LEVEL >= LoggingLevel::ERROR)
this->log_(LoggingLevel::ERROR, msg.c_str());
}
// …
private:
LoggingLevel level_;
void
log_(LoggingLevel, const char *) const;
};
As long as evaluating the function arguments for your Logger::logError etc calls does not have visible side-effects, chances are good that the compiler will eliminate the call if the conditional in the inline function is false. This is why I have added the overloads that take a raw C-string to optimize the frequent case where the function is called with a string literal. Look at the assembly to be sure.
Personally I wouldn't have a a lot of #ifdef DEBUG scattered around my code:
#ifdef DEBUG
printf("something");
#endif
// some code ...
#ifdef DEBUG
printf("something else");
#endif
rather, I would wrap it in a function:
void DebugPrint(const char const *debugText) // ToDo: make it variadic [1]
{
#ifdef DEBUG
printf(debugText);
#endif
}
DebugPrint("something");
// some code ...
DebugPrint("something else");
If you don't define DEBUG then the macro preprocessor (not the compiler) won't expand that code.
The slight downside of my approach is that, although it makes your cod cleaner, it imposes an extra function call, even if DEBUG is not defined. It is possible that a smart linker will realize that the called function is empty and will remove the function calls, but I wouldn't bank on it.
References:
“Variadic function” in: Wikipedia, The Free Encyclopedia.
I also would suggest to use inline functions which become empty if a flag is set. Why when it is set? Because you usually want to debug always unless you compile a release build.
Because NDEBUG is already used you could use it too to avoid using multiple different flags. The definition of a debug level is also very useful.
One more thing to say: Be careful using functions which are altered by using macros! You could easily violate the One Definition Rule by translating some parts of your code with and some other without debugging disabled.
You might follow the convention of assert(3) and wrap debugging code with
#ifndef NDEBUG
DebugPrint("something");
#endif
See here (on StackOverflow, which would be a better place to ask) for a practical example.
In a more C++ like style, you could consider
ifdef NDEBUG
#define debugout(Out) do{} while(0)
#else
extern bool dodebug;
#define debugout(Out) do {if (dodebug) { \
std::cout << __FILE__ << ":" << __LINE__ \
<< " " << Out << std::endl; \
}} while(0)
#endif
then use debugout("here x=" << x) in your program. YMMV. (you'll set your dodebug flag either thru a gdb command or thru some program argument, perhaps parsed using getopt_long(3), at least on Linux).
PS. Remind that the do{...}while(0) is an old trick to make a robust statement like macro (suitable in every position where a plain statement is, e.g. as the then or else part of an if etc...).
You could also use templates utilizing the constexpr if feature in C++17. you don't have to worry about the preprocessor at all but your declaration and definition have to be in the same place when using templates.
I have the following problem:
Let's consider we have
#define SET callMe
#define COLUMN(x) #x
and in our main block of our program we have the following line:
SET(COLUMN(price)="hi"); which after the preprocessor running is translated to:
#callMe("price"="hi");
I need function callMe signature to be callMe(string str) so that leaves us to have to make something to make the "price"="hi" to "price=hi" and let callMe function to handle the rest of the problem. Last thing to state is that all this program I describe is a part of a Table class.
The only option I have is overload the operator = so the "price"="hi" translated to the wanted one, but I can't get what I should overload because I first thought that doing the following overload
#std::string operator=(std::string str) as a member function of the Table class but it seems I can't get it right on track.
Any clues of how I can achieve the wanted operations?
Is this any good to you?
#define SECOND_PASS(x) callMe(#x)
#define COLUMN(x) x
#define SET(x) SECOND_PASS(x)
which results in:
callMe("price=\"hi\"");
This essentially gets the preprocessor to remove COLUMN before converting to a string.
To get what you want, you would have to write your code as SET(COLUMN(price)"=hi").
You can't overload operator=() for a built-in type. This is done for sanity maintenance, among other reasons.
C++ overloading is not intended to allow you to force the compiler to parse a different language.
P.S. Overloading operator=() in the Table class only handles the case where a Table is on the left-hand side of the =. That would require COLUMN(x) to return a Table object, probably not what you want. You could use an adaptor class to get this effect, but the syntax of COLUMN(x) doesn't include which table this column is from, so you're stuck there too.
One way out there solution would look something like this:
class ColumnSetter
{public:
ColumnSetter(const char* name): name(name), value(0) {}
ColumnSetter& operator=(const char* value_) { value = value_; }
operator std::string const &() const { std::string result(name);
if(value) { result.append('='); result.append(value); } return result; }
private:
const char* name;
const char* value;
};
#define COLUMN(x) ColumnSetter(#x)
void callMe(const std::string& param);
Reformat and de-inline to whatever coding standards you have.
You mean like
#define SET(x) (CallMe(x))
ps - usual disclaimer about using the preprocessor
This should be done with classes that overload the various logical operators to create an abstract syntax tree instead of actually performing the operation. Then you can express various SQL expressions as C++ code and get an abstract syntax tree out which can then be serialized into an SQL WHERE clause.
This isn't very hard, and if you are careful about it, it will be pretty efficient. It's much better than trying to use preprocessor hackery to create an SQL expression builder.
I have sort of a tricky problem I'm attempting to solve. First of all, an overview:
I have an external API not under my control, which is used by a massive amount of legacy code.
There are several classes of bugs in the legacy code that could potentially be detected at run-time, if only the external API was written to track its own usage, but it is not.
I need to find a solution that would allow me to redirect calls to the external API into a tracking framework that would track api usage and log errors.
Ideally, I would like the log to reflect the file and line number of the API call that triggered the error, if possible.
Here is an example of a class of errors that I would like to track. The API we use has two functions. I'll call them GetAmount, and SetAmount. They look something like this:
// Get an indexed amount
long GetAmount(short Idx);
// Set an indexed amount
void SetAmount(short Idx, long amount);
These are regular C functions. One bug I am trying to detect at runtime is when GetAmount is called with an Idx that hasn't already been set with SetAmount.
Now, all of the API calls are contained within a namespace (call it api_ns), however they weren't always in the past. So, of course the legacy code just threw a "using namespace api_ns;" in their stdafx.h file and called it good.
My first attempt was to use the preprocessor to redirect API calls to my own tracking framework. It looked something like this:
// in FormTrackingFramework.h
class FormTrackingFramework
{
private:
static FormTrackingFramework* current;
public:
static FormTrackingFramework* GetCurrent();
long GetAmount(short Idx, const std::string& file, size_t line)
{
// track usage, log errors as needed
api_ns::GetAmount(Idx);
}
};
#define GetAmount(Idx) (FormTrackingFramework::GetCurrent()->GetAmount(Idx, __FILE__, __LINE__))
Then, in stdafx.h:
// in stdafx.h
#include "theAPI.h"
#include "FormTrackingFramework.h"
#include "LegacyPCHIncludes.h"
Now, this works fine for GetAmount and SetAmount, but there's a problem. The API also has a SetString(short Idx, const char* str). At some point, our legacy code added an overload: SetString(short Idx, const std::string& str) for convenience. The problem is, the preprocessor doesn't know or care whether you are calling SetString or defining a SetString overload. It just sees "SetString" and replaces it with the macro definition. Which of course doesn't compile when defining a new SetString overload.
I could potentially reorder the #includes in stdafx.h to include FormTrackingFramework.h after LegacyPCHIncludes.h, however that would mean that none of the code in the LegacyPCHIncludes.h include tree would be tracked.
So I guess I have two questions at this point:
1: how do I solve the API overload problem?
2: Is there some other method of doing what I want to do that works better?
Note: I am using Visual Studio 2008 w/SP1.
Well, for the cases you need overloads, you could use a class instance that overloads operater() for a number of parameters.
#define GetAmount GetAmountFunctor(FormTrackingFramework::GetCurrent(), __FILE__, __LINE__)
then, make a GetAmountFunctor:
class GetAmountFunctor
{
public:
GetAmountFunctor(....) // capture relevant debug info for logging
{}
void operator() (short idx, std::string str)
{
// logging here
api_ns::GetAmount(idx, str);
}
void operator() (short idx)
{
/// logging here
api_ns::GetAmount(Idx);
}
};
This is very much pseudocode but I think you get the idea. Whereever in your legacy code the particular function name is mentioned, it is replaced by a functor object, and the function is actually called on the functor. Do consider you only need to do this for functions where overloads are a problem. To reduce the amount of glue code, you can create a single struct for the parameters __FILE__, __LINE__, and pass it into the constructor as one argument.
The problem is, the preprocessor doesn't know or care whether you are calling SetString or defining a SetString overload.
Clearly, the reason the preprocessor is being used is that it it oblivious to the namespace.
A good approach is to bite the bullet and retarget the entire large application to use a different namespace api_wrapped_ns instead of api_ns.
Inside api_wrapped_ns, inline functions can be provided which wrap counterparts with like signatures in api_ns.
There can even be a compile time switch like this:
namespace api_wrapped_ns {
#ifdef CONFIG_API_NS_WRAPPER
inline long GetAmount(short Idx, const std::string& file, size_t line)
{
// of course, do more than just wrapping here
return api_ns::GetAmount(Idx, file, line);
}
// other inlines
#else
// Wrapping turned off: just bring in api_ns into api_wrapper_ns
using namespace api_ns;
#endif
}
Also, the wrapping can be brought in piecemeal:
namespace api_wrapped_ns {
// This function is wrapped;
inline long GetAmount(short Idx, const std::string& file, size_t line)
{
// of course, do more than just wrapping here
return
}
// The api_ns::FooBar symbol is unwrapped (for now)
using api_ns::FooBar;
}