The format of define preprocessor directives are:
#ifndef SIZE
#define SIZE 10
int hello[SIZE];
#endif
But when I look at the following code, there is no replacement for the preprocessor directives:
#ifndef CREDIT_CARD_H // Avoid repeated expansion
#define CREDIT_CARD_H
#include <string> // Provides string
#include <iostream> // Provides ostream
class CreditCard
{
public:
CreditCard(const std::string& no, // Constructor
const std::string& nm, int lim, double bal = 0);
// Accessor functions
std::string getNumber()const { return number; }
std::string getName() const { return name; }
double getBalance() const { return balance; }
int getLimit() const { return limit; }
bool chargeIt(double price); // Make a charge
void makePayment(double payment); // Make a payment
private: // Private member data
std::string number; // Credit card number
std::string name; // Card owner's name
int limit; // Credit limit
double balance; // Credit card balance
};
std::ostream& operator<<(std::ostream& out, const CreditCard& c);
#endif
What does this mean?
You can say #define FOO, which means that #ifdef FOO will be true, but FOO doesn't have any replacement text. This is useful precisely for conditional checks like the include guards.
It can also be useful for platform-specific extensions, which you want to be empty in the general case:
#ifdef WIN32
# define API __declspec(dllexport)
#else
# define API
#endif
API void foo();
That type of directive pastes in the file depending on the condition:
#ifndef SIZE
//whatever
#endif
Whatever is between the #ifndef and #endif is seen by the compiler only if SIZE wasn't defined.
The same happens for the second piece of code:
#ifndef CREDIT_CARD_H // avoid repeated expansion
#define CREDIT_CARD_H
//....
#endif
The class definition and includes will only be seen if CREDIT_CARD_H was not defined beforehand. This is known as an include guard.
You don't have to define a macro as something, you can just say #ifdef SIZE without actually "setting" size to anything, just defining it.
It's an include guard to ensure that the file only gets included once.
#include "CreditCard.h"
#include "CreditCard.h"
The second time it's included CREDIT_CARD_H is already defines so it skips the whole definition.
Now you wouldn'd directly include a file twice like that, but it's common that one include file includes another and this stops any duplication definitions from happening.
The actual value is never used, only the fact that it's now defined
I think what you are looking for is #pragma once
https://en.wikipedia.org/wiki/Pragma_once
Related
suppose you have to write code that should compile under C++,C++11,C++17,etc.
A function like this for example.
bool Ispalindrome(const std::string &str)
{
// Code
}
That compiles under all C++ implementations. But if you want to use the old and the new the C++17 string_view feature you have deal with something similar to
#ifdef LEGACYCPP
bool Ispalindrome(const std::string &str)
{
// Code
}
#elseif CPP17
bool Ispalindrome(std::string_view str)
{
// OMG Repeated Code
}
#endif
Using conditional compiling is right, but have to repeat code.
Is there any way to choose a function prototype at compile time ? Or other way to circumvent double coding ? (in situations where it can be applied)
Thanks
In a header file, you'll need to do something like
#if __cplusplus >= 201703L
#include <string_view>
bool Ispalindrome(std::string_view str);
#else
#include <string>
bool Ispalindrome(const std::string &str);
#endif
In your definition, you'll need to include the header and then do
#if __cplusplus >= 201703L
bool Ispalindrome(std::string_view str)
#else
bool Ispalindrome(const std::string &str)
#endif
{
// OMG no repeated code
}
__cplusplus is specified in the standard, and is predefined in every compilation unit. 201703L indicates a C++17 compiler, larger values more recent standards.
This assumes an implementation (compiler and library) that correctly claims compliance with the respective C++ standard.
If you can be sure that the code section of your function will be equivalent in each case, then you can use a macro definition for the parameter list:
#ifdef ISCPP17
#define PALIN_PARAMS std::string_view str
#else
#define PALIN_PARAMS const std::string& str
#endif
bool Ispalindrome(PALIN_PARAMS)
{
// Code
}
#undef PALIN_PARAMS
There are, of course, many variations on this theme: you could leave out the "str" part in the macro definition and have (PALIN_PARAMS str) in the signature. But, using "as is" will also allow for multiple parameters with different types.
But I'm not sure this sort of thing will pass the Inquisitions of the C++ Puritans.
Another (possibly more robust) way would be to use conditional compilation blocks with using (or typedef) statements to define argument types:
#ifdef ISCPP17
using cnststrg = std::string_view; // Or typedef std::string_view cnststrg;
#else
using cnststrg = const std::string&;
#endif
bool Ispalindrome(cnststrg str)
{
// Code
return true;
}
Provided it's exactly repeated code then, do following minor change:
#ifdef CPP17
bool Ispalindrome(std::string_view str)
#else // all versions of LEGACYCPP
bool Ispalindrome(const std::string &str)
#endif
{
// Same Code
}
If a minor part of function is unique to versions, then apply the above same trick there too.
Is it bad practice to put #endif at the beginning of a c++ header file after #ifndef and #define? If so, why?
This question does not touch on why #endif is at the end - which is specifically what i was googling for.
For example
//cDate.h
#ifndef CDATE_H_EXISTS
#define CDATE_H_EXISTS
#include <string>
class cDate {
private:
std::string day;
std::string month;
std::string year;
public:
void setDate(std::string, std::string, std::string);
std::string getDate(int);
}; // end class def
#endif
vs
//cDate.h
#ifndef CDATE_H_EXISTS
#define CDATE_H_EXISTS
#endif
#include <string>
class cDate {
private:
std::string day;
std::string month;
std::string year;
public:
void setDate(std::string, std::string, std::string);
std::string getDate(int);
}; // end class def
First example, it is include guard
Second example, it is nothing-guard.
It doesn't accomplish its task; including this header file again will include all the lines again.
Consider the if statements:
if (condition) {
<do something>
}
vs.
if (condition) {
(void) 0;
}
<do something>
The condition is the #ifndef (if not defined), the opening brace is the initial condition, and the closing brace is the #endif.
You need to exclude the full contents of the file if it's already processed.
The purpose is not to #define the header guard - that's a useful(ish) side effect. The purpose is to ensure the header content is loading only once.
While, subtle, the difference is huge. Assuming you were to place the #endif right after your #define statement at the top, that definition would be completely blank, and if there is a situation where your header file is being included more than once, the file will still be compiled and cause issues because nothing was defined.
Once the flip side, the #endif is supposed to be at the very end to set the definition as the ENTIRE file and its code contents, so that if it is included more than once, none of the file will be executed in excess.
Any help on why I am getting a 'C2011 'Transaction':'class' type redefinition? I'm sure it's glaringly obvious but I cannot for the life of me figure it out. Please help.
transaction.h
#include <string>
class Transaction
{
private:
int amount;
std::string type;
public:
Transaction(int amt, std::string kind);
std::string Report();
};
transaction.cpp
#include "transaction.h"
using namespace std;
Transaction::Transaction(int amt, std::string kind):amount(amt), type(kind)
{
}
string Transaction::Report()
{
string report;
report += " ";
report += type;
report += " ";
report += to_string(amount);
return report;
}
You can either use a header guard in the header file which will make sure you never ever more than once define a class or struct etc. in any other cpp file.
To add a header guard you can simply do this:
#ifndef TRANSACTION_H
#define TRANSACTION_H
// your header file
#endif
Or simply add
#pragma once
to all your header files and you're good.
You need to use include guards in transaction.h:
#if !defined(your_symbol)
#define your_symbol 1
/*ToDo - code here*/
#endif
Where, your_symbol is typically an embellishment of the name of the file. Be careful not to use a leading double underscore or a single leading underscore followed by a capital letter as they are reserved symbols.
This prevents the class declaration from being included more than once in any compilation unit.
You can use #ifndef your_symbol in place of my first line, and drop the 1 from the second line, or perhaps even just use a #pragma once directive at the top of the file, but the version I present works on every compiler I've ever come across.
In your header try this:
#ifndef TRANSACTION //If transaction has never been defined before
#define TRANSACTION //Define transaction
//Content of your header
#endif
This header guard will probably help you. Indeed it will prevent your header from being included multiple times which leads to redefinitions. If you include your header just once you don't need these guards, but it doesn't hurt to have them anyway.
Alternatively, you can use #pragma once at the beginning of your header.
If you want to read more about them, check wikipedia
I'm trying to implement logging which produce no overhead when not needed (i.e. no method call should be performed at all). I want NO overhead because it's low-latency code. I just added #define ENABLE_LOGS to my header class and now it looks like that (you can ignore details)
#pragma once
#include <string>
#include <fstream>
#define ENABLE_LOGS
namespace fastNative {
class Logger
{
public:
Logger(std::string name_, std::string fileName, bool append = false);
~Logger(void);
void Error(std::string message, ...);
void Debug(std::string message, ...);
void DebugConsole(std::string message, ...);
void Flush();
static Logger errorsLogger;
static Logger infoLogger;
private:
FILE* logFile;
bool debugEnabled;
};
}
Every time I need to use some method I should surround it like that:
#ifdef ENABLE_LOGS
logger.Debug("seq=%6d len=%4d", seq, length_);
#endif
It's error-phrone (i can forgot to surround) and makes code dirty. Can I fix my code somehow not to use #ifdef every time?
In C# I like Conditional I guess I need something like that for c++.
First of all it would make sense to have a look to see what's out there already. This is a common problem and many people will have solved it before. E.g., see stackoverflow question C++ logging framework suggestions, and Dr Dobbs A Highly Configurable Logging Framework In C++.
If you do roll your own, you should get some good ideas from having done this. There are several approaches I've used in the past. One is to make the statement itself conditionally defined
#ifdef ENABLE_LOGS
#define LOG(a,b,c) logger.Debug(a, b, c)
#else
#define LOG(a,b,c)
#endif
Another approach is to conditionally define the logging class itself. The non-logging version has everything as empty statements, and you rely on the compiler optimizing everything out.
#ifdef ENABLE_LOGS
class Logger
{
public:
Logger(std::string name_, std::string fileName, bool append = false);
~Logger(void);
void Error(std::string message, ...);
void Debug(std::string message, ...);
void DebugConsole(std::string message, ...);
void Flush();
static Logger errorsLogger;
static Logger infoLogger;
private:
FILE* logFile;
bool debugEnabled;
};
#else
class Logger
{
public:
Logger(std::string name_, std::string fileName, bool append = false) {}
~Logger(void) {}
void Error(std::string message, ...) {}
void Debug(std::string message, ...) {}
void DebugConsole(std::string message, ...) {}
void Flush() {}
};
#endif
You could put your Logger implementation for ENABLE_LOGS in a cpp file under control of the macro. One issue with this approach is that you would want to be sure to define the interface so the compiler could optimize everything out. So, e.g., use a C-string parameter type (const char*). In any case const std::string& is preferable to std::string (the latter ensures there's a string copy every time there's a call).
Finally if you go for the first approach, you should encapsulate everything in do() { ... } while(0) in order to ensure that you don't get bizarre behavior when you use your macro where a compound statement might be expected.
There is one way (the way llvm does) to do this using macros.
#ifdef ENABLE_LOGS
#define DEBUG(ARG) do { ARG; } while(0)
#else
#define DEBUG(ARG)
#endif
Then use it as:
DEBUG(logger.Debug("seq=%6d len=%4d", seq, length_););
What I often see, is to use the #define to actually define the log calls, eg:
#define LOG_DEBUG(msg) logger.Debug(msg);
But you want to wrap the defines in a block that enables or disables your logging:
#ifdef ENABLE_LOGS
#define LOG_DEBUG(msg) logger.Debug(msg);
#else
#define LOG_DEBUG(msg)
#endif
You can call LOG_DEBUG anywhere in your code. If the logging is disabled, calling LOG_DEBUG ends up as a blank line in your final code.
A nice old trick is:
#ifdef ENABLE_LOGS
#define LOG Logger.Debug
#else
#define LOG (void)sizeof
#endif
Then the code:
LOG("seq=%6d len=%4d", seq, length_);
will expand to:
Logger.Debug("seq=%6d len=%4d", seq, length_);
that does the log. Or:
(void)sizeof("seq=%6d len=%4d", seq, length_);
that does absolutely nothing. It doesn't even evaluate the function arguments!!!
The trick is that the first version uses the comma as argument separator in a function call. In the second version, however, it is a unevaluated comma operator.
However, some compilers may give spurious warnings about unreachable code.
You could put the #ifdef inside the body of the individual functions. This avoid the code duplication issue in TooTone's answer.
Example:
void fastNative::Logger::Debug(std::string message, ...)
{
#ifdef ENABLE_LOGS
// do the actual logging
#endif
}
If ENABLE_LOGS isn't defined, this function doesn't do anything. What I would suggest is you pass a const char* instead of std::string to these method. That way, if ENABLE_LOGS is not defined, you wouldn't have to rely on the compiler to not create redundant std::string objects.
I have two macros that declares class properties:
DECLARE_QUERY_PARAM_LONG(name)
DECLARE_QUERY_PARAM_STRING(name)
I want to count number of calls of this macros inside of my class and init
static const size_t paramsCount
with that number like this:
class MyClass {
...
DECLARE_QUERY_PARAM_LONG(param1)
DECLARE_QUERY_PARAM_STRING(param2)
DECLARE_QUERY_PARAM_STRING(param3)
DECLARE_QUERY_PARAM_LONG(param4)
static const size_t paramsCount = PARAMS_COUNT; // 4 in this case
...
};
Is this ever possible?
There would be a solution, rather complicated:
All your parameters will have a fixed name (say param)
You need to create one header file per type
You shall need boost
So here is the header creation file:
// file declare_int.h
#include BOOST_PP_UPDATE_COUNTER()
int stringize(param,BOOST_PP_COUNTER) ;
and the class file:
//file declare_auto.cpp
#include <boost/preprocessor/slot/counter.hpp>
#define _stringize(a,b) a##b
#define stringize(a,b) _stringize(a,b)
// reset counter
#if defined(BOOST_PP_COUNTER)
#undef BOOST_PP_COUNTER
#endif
class A {
public:
#include "declare_int.h"
#include "declare_int.h"
#include "declare_int.h"
#include "declare_int.h"
static const int nbParams = BOOST_PP_COUNTER ;
};
and finally the output of:
g++ -E -P -c declare_auto.cpp -IPATH_TO_BOOST
is
class A {
public:
int param1 ;
int param2 ;
int param3 ;
int param4 ;
static const int nbParams = 4 ;
};
You can at least count number of lines in the following way:
class MyClass
{
static const int line_1 = __LINE__;
DECLARE_QUERY_PARAM_LONG(param1)
DECLARE_QUERY_PARAM_STRING(param2)
DECLARE_QUERY_PARAM_STRING(param3)
DECLARE_QUERY_PARAM_LONG(param4)
static const int line_2 = __LINE__;
static const int macro_calls = line_2 - line_1 - 1;
public:
MyClass()
{
cout << macro_calls << endl;
}
};
But I think you'll need C++11 to do that. And You cannot have empty lines within those two __LINE__s. Otherwise, you'll have to count those empty lines as well.
As such no.
What you are asking for would require some form of introspection, which is not natively supported by C++.
You can improve the macro though, if you had:
DECLARE_QUERY_PARAMS(((LONG , param1))
((STRING, param2))
((STRING, param3))
((LONG , param4)))
then you could do what you want.
You can have a look at Boost.Preprocessor to learn how to obfuscate your sources this way.
Note: this uses a Sequence, in boost parlance.
I don't think there's a standard way to do this, but the DevStudio compiler has this preprocessor macro:
__COUNTER__
Expands to an integer starting with 0 and incrementing by 1 every time it is used in a compiland. __COUNTER__ remembers its state when using precompiled headers. If the last __COUNTER__ value was 4 after building a precompiled header (PCH), it will start with 5 on each PCH use.
__COUNTER__ lets you generate unique variable names. You can use token pasting with a prefix to make a unique name. For example:
// pre_mac_counter.cpp
#include <stdio.h>
#define FUNC2(x,y) x##y
#define FUNC1(x,y) FUNC2(x,y)
#define FUNC(x) FUNC1(x,__COUNTER__)
int FUNC(my_unique_prefix);
int FUNC(my_unique_prefix);
No. Macro's don't respect scope at all, and don't understand that they're inside a class.
No. Macros aren't executed, they're expanded and not even by compiler, but by preprocessor.