using #if to use old / new method code - if-statement

I have question is possible use #if to use old / new method.
Example:
#if (Old)
public void method1()
{
//code
}
#else
public void method1()
{
//code
}
#endif

If you're referring to C#:
You can do this, see here for an example:
http://msdn.microsoft.com/en-us/library/aa691099(v=vs.71).aspx
Remove the brackets around Old in your example, and #define Old or don't.
Typically you would define the directives in the project properties under a build configuration.

Related

How to define a macro that resolves to either method name or no operation?

In the code base I have many sections that are either turned on or off depending on enabled features. The aim is to generate program code as small as possible (Arduino with 32kB program memory).
Lets say I have the code as below:
class A
{
private:
#ifdef FEATURE
int m_optA;
int m_optB;
#endif
public:
#ifdef FEATURE
void SetFeatureOptions(int optionA, int optionB)
{
m_optA = optionA;
m_optB = optionB;
}
#endif
};
#ifdef FEATURE
#define SETFEATUREOPTIONS(a, b) SetFeatureOptions(a, b)
#else
#define SETFEATUREOPTIONS(a, b) Noop() // ????? <-- what should I put here to perform NOOP
#endif
class B
{
public:
A m_a;
void DoStuff()
{
// approach 1:
#ifdef FEATURE
m_a.SetFeatureOptions(1, 34);
#endif
// approach 2:
// Lets have a macro - see above
// This way each time I want to call SetFeatureOptions but only when FEATURE is defined
// I need no ifdef/endif scope to be used explicitely.
m_a.SETFEATUREOPTIONS(1, 34);
}
}
Is there a way to resolve SETFEATUREOPTIONS macro so it compiles and yet doesn't generate any code, when called as a method name?
Why way is to implement Noop() method in class A, but I was wondering if there is better way, that is not requiring adding a null method like mentioned above Noop(). I am not sure if adding inline Noop(){} will add some bytes to the program memory or not (Release, optimized code).
IMPORTANT: This has to compile with C++98 compiler.
Just write:
void SetFeatureOptions(int optionA, int optionB)
{
#ifdef FEATURE
m_optA = optionA;
m_optB = optionB;
#endif
}
and make sure you compile with optimizations turned on. Your compiler is smart enough to delete the function call, if the function is defined in the header file and is empty.
If the function is defined in a different .cpp file the compiler won't know it's empty, so it won't delete the call.

How to override "default" #define values ​of a C ++ library header with new values ​defined in an application header

What I'm trying to do is provide a library with some defaults set by #define directives in the library header. Those would determine what functions of the library code will be compiled with a given application. In case the application developer needs to add or remove library functions, it should "override" the library's defaults ​​with new values ​​without modifying the library. Besides modifying the library compiled code, those application header's #define values will, in turn, add or remove parts of the application code itself. This is for an embedded system, so even small memory savings are important.
Below are the 4 test files. I can't get it working if it's even possible to do this. Maybe the right question is: What's the correct order of #define / #undef inside the project files?
library.h:
#ifndef MY_LIBRARY_H
#define MY_LIBRARY_H
#include <stdio.h>
#define FUNCTION_1 true
#define FUNCTION_2 false
class Class {
public:
Class();
~Class();
#if FUNCTION_1
void Function_1(void);
#endif
#if FUNCTION_2
void Function_2(void);
#endif
};
#endif // MY_LIBRARY_H
library.cpp:
#include "library.h"
Class::Class() { /* Constructor */ };
Class::~Class() { /* Destructor */ };
#if FUNCTION_1
void Class::Function_1(void) {
printf("Hi, this is %s running ...\n\r", __func__);
}
#endif
#if FUNCTION_2
void Class::Function_2(void) {
printf("Hi, this is %s running ...\n\r", __func__);
}
#endif
tst-09.h
#ifndef TST_09_H
#define TST_09_H
#include <library.h>
#undef FUNCTION_2 // .....................................................
#define FUNCTION_2 true // THIS IS WHERE I'M TRYING TO OVERRIDE THE LIB DEFAULTS
#endif // TST_09_H
tst-09.cpp:
#include "tst-09.h"
int main(void) {
Class object;
#if FUNCTION_1
object.Function_1();
#endif
#if FUNCTION_2
object.Function_2();
#endif
}
Take advantage of the capabilities of your linker. If you want to exclude unused or unnecessary code from you binary, one way to do that is to put each function in its own source module. (Some compiler packages support Function Level Linking, where the linker can remove unreferenced functions.)
Trying to use macros the way you show in your question would need them to be defined on the command line (and the library rebuilt with any change).

How can I create a platform-independent macro to wrap a compiler extension?

I have some code like this that I need to make cross-platform:
int __attribute__((noinline)) fn() { return 0; }
I want to use Waf to write a config.h that contains
#define ATTRIBUTE(attr) __attribute__((attr))
if the compiler supports this extension, and
#define ATTRIBUTE(attr)
otherwise, so I can rewrite the function like this:
int ATTRIBUTE(noinline) fn() { return 0; }
Looking at the configuration documentation I don't see an obvious way to do this. The best I could do is define some HAS_ATTRIBUTES macro if a code snippet using this feature fails to compile.
Does waf support configuring the project in this manner, or will I have to write a second config header manually?
(I am specifically looking for a waf answer. If I could use something else, I would.)
Here is how I solved it.
In my wscript:
attribute_noinline_prg = '''
int __attribute__((noinline)) fn() { return 0; }
int main()
{
return fn();
}
'''
conf.check_cxx(fragment=attribute_noinline_prg,
msg='Checking for __attribute__(noinline)',
define_name='HAVE_ATTRIBUTE_NOINLINE',
mandatory=False)
And then in a manually-created config header:
#ifdef HAVE_ATTRIBUTE_NOINLINE
#define ATTRIBUTE_NOINLINE __attribute__((noinline))
#else
#define ATTRIBUTE_NOINLINE
#endif
I would have hoped to avoid manually creating the header like this, but it does the job.

C++ __declspec( dllexport ) functions cannot access instance variables

I am trying to protect some C++ code by exporting as a DLL (on Windows/VS 2010).
In the example below var is set in the superclass constructor, and the debugger shows it is definitely set to reference something.
Test is constructed in the code that consumes the DLL the Test class is contained within.
But when go is called from on an instance of test (invoked from the DLL, but the invoking method is called by the DLL consumer) var is a null pointer (it's value is 0).
This is a simplification as I am not allowed to share the actual code.
//Headers
class Base {
public:
__declspec(dllexport) Base();
private:
Foo* var;
};
class Test : Base {
public:
__declspec(dllexport) Test();
__declspec(dllexport) void go();
private:
};
//Body
Base::Base() {
var = new Foo();
}
Test::Test() : Base() {
}
void Test::go() {
var->do_something();
}
In the consuming code, the header is
class Base {
public:
__declspec(dllimport) Base();
};
class Test {
public:
__declspec(dllimport) Test();
__declspec(dllimport) void go();
};
The actual code is much more complex, but I would be grateful if anyone can tell me whether there are known restrictions on instance variables with dllexport, or if it is more likely that I'm calling a method on a null pointer for Test, or perhaps it is a dllexport and inheritance problem. This code worked before I split the consumer code and DLL code was in the same project, it has only broken since splitting it up, dllexporting/dllimporting functions I want to expose into a second set of headers used by the consumer.
When you pass a Test by value from one place to another in the "consuming code", you'll cause slicing to occur because the client code is unaware of the variable and calculates an incorrect size for the class Test.
To solve this problem, you should declare the variable in the client code as well, or alternatively you can provide a static factory function of some kind and only allow the client code to pass pointers to Tests around to avoid slicing.
If you remove the instance variable from the code supplied to the customer, only your own code knows the real size of your object and can create it. From the top of my head you have two ways to go about this:
Supply a createTest static function that creates an instance of your class (factory method). The nicest thing to do here is to provide a pure interface (no instance variable).
If you only want to hide a specific part of your class you can use the pimpl idiom (wikipedia article).
Is there any reason to not use:
#ifdef IN_FOO_PROJECT
# define fooEXPORT __declspec(dllexport)
#else
# define fooEXPORT __declspec(dllimport)
#endif
class fooEXPORT exportClass
{
public:
void function( void );
Foo * var;
}
If you want to hide your class (or part of your class), you could use it as a private member:
#ifdef IN_FOO_PROJECT
# define fooEXPORT __declspec(dllexport)
#else
# define fooEXPORT __declspec(dllimport)
#endif
class classToHide;
class fooEXPORT exportClass
{
public:
void function( void );
classToHide * var;
}
And in Cpp:
#include "exportClass.h"
#include "classToHide.h"
void exportClass::function( void )
{
var->function();
}

Why am I getting "too many include files : depth = 1024"?

I'm using Visual Studio 2008 Express edition, and keep getting the following error:
"Cascadedisplay.h(4) : fatal error C1014: too many include files : depth = 1024.
Obviously I'm doing something very wrong with include files, but I just can't see what.
Basically, I have an interface class, StackDisplay, from which I want to derive CascadeDisplay in another file:
#if !defined __BASE_STACK_DISPLAY_H__
#define __BASE_STACK_DISPAY_H__
#include <boost\shared_ptr.hpp>
#include "CascadeDisplay.h"
namespace Sol
{
class StackDisplay
{
public:
virtual ~StackDisplay();
static boost::shared_ptr<StackDisplay>
make_cascade_display(boost::shared_ptr<int> csptr)
{
return boost::shared_ptr<StackDisplay>(new CascadeDisplay(csptr));
}
};
}
#endif
and then in CascadeDisplay.h:
#if !defined __CASCADE_DISPLAY_H__
#define __CASCADE_DISPAY_H__
#include "StackDisplay.h"
#include <boost\shared_ptr.hpp>
namespace Sol
{
class CascadeDisplay: public StackDisplay
{
public:
CascadeDisplay(boost::shared_ptr<int> csptr){};
};
}
#endif
So what's up with that?
#if !defined __CASCADE_DISPLAY_H__
#define __CASCADE_DISPAY_H__
Second line should be:
#define __CASCADE_DISPLAY_H__
Same with:
#if !defined __BASE_STACK_DISPLAY_H__
#define __BASE_STACK_DISPAY_H__
Also, names that contain a double-underscore are reserved for the implementation, you are not allowed to create such names in your own code. Same goes for names that begin with a single underscore and an uppercase letter.
There is a typo in your guards
#if !defined __CASCADE_DISPLAY_H__ <--- here you have DISPLAY
#define __CASCADE_DISPAY_H__ <--- here you have DISPAY (no L!)
and yes, avoid double underscores in such names
Is #if !defined... legit? I always used #ifndef.
Either way, why does your "base" class require the reference to CascadeDisplay? That doesn't seem right. Consider replacing your call to create a new CascadeDisplay with a call to a pure virtual function in StackDisplay that your subclass must implement appropriately.
IE, something like (and forgive, I don't have a c++ compiler handy to check this):
namespace Sol
{
class StackDisplay
{
public:
virtual ~StackDisplay();
boost::shared_ptr<StackDisplay>
make_cascade_display(boost::shared_ptr<int> csptr)
{
return make_display(csptr);
}
protected:
virtual boost::shared_ptr<StackDisplay> make_display(boost::shared_ptr<int> csptr) = 0;
};
class CascadeDisplay: public StackDisplay
{
public:
CascadeDisplay(boost::shared_ptr<int> csptr){};
protected:
virtual boost::shared_ptr<StackDisplay> make_display(boost::shared_ptr<int> csptr)
{
return new CascadeDisplay(csptr);
}
};
}
I believe this solution is superior, in general, to the forward declaration because you're eliminating some tight coupling between your superclass and your subclass, and making a more generic interface besides. This lets you eliminate the #include of CascadeDisplay.h in StackDisplay.h.