I need to generate a series of sequential numbers throughout my code at compile time. I tried "__COUNTER__" in a way like this:
void test1()
{
printf("test1(): Counter = %d\n", __COUNTER__);
}
void test2()
{
printf("test2(): Counter = %d\n", __COUNTER__);
}
int main()
{
test1();
test2();
}
And the result was perfect as I expected:
test1(): Counter = 0
test2(): Counter = 1
Then I spread "__COUNTER__" out in different .cpp files:
In Foo.cpp:
Foo::Foo()
{
printf("Foo::Foo() with counter = %d\n", __COUNTER__);
}
In Bar.cpp:
Bar::Bar()
{
printf("Bar::Bar() with counter = %d\n", __COUNTER__);
}
In Main.cpp:
int main()
{
Foo foo;
Bar bar;
}
The result was:
Foo::Foo() with counter = 0
Bar::Bar() with counter = 0
It looks to me that "__COUNTER__" is provided as a per compile unit variable.
What I'd like to have is a global counter that's effective throughout the code.
This is used for testing in a debug build where I want to achieve this goal:
Imagine that I have try/catch blocks throughout the code (a subsystem or a module within multiple .cpp files). At run time the program is running in a loop, within each loop all the try blocks will be executed in orders (in which order doesn't matter), and I want to test how the code react to exception for each try/catch, one by one. For example, the first time in the loop, #1 try/catch block throws an exception; second time in the loop, #2 try/catch block throws an exception, etc etc.
I plan to have a global counter like this:
int g_testThrowExceptionIndex = 0;
In each try/catch:
try
{
TEST_THROW_EXCEPTION(__COUNTER__)
//My logic is here...
}
catch(...)
{
//Log or notify...
}
And the Macro would be something like this:
#define TEST_THROW_EXCEPTION(n) \
if(g_testThrowExceptionIndex == n)\
{\
g_testThrowExceptionIndex++;\
throw g_testThrowExceptionIndex;\
}\
Without the ability to generate the sequence number at compile time, I have to write the Macro like this:
TEST_THROW_EXCEPTION(THROW_INDEX_1)
......
TEST_THROW_EXCEPTION(THROW_INDEX_N)
And in the header, defines:
#define THROW_INDEX_1 0
#define THROW_INDEX_2 1
......
The problem is, every time you add a try/catch block and you want to test, you have to create a new constant through #define and put that number into the Macro. Worse, what if you remove some of the try/catch blocks from the code? You have to update your #define list too...
==============
Solution:
Thanks for Suma's idea, I ended up with something like this:
#if defined(_DEBUG) && defined(_EXCEPTION_TEST)
extern int g_testThrowExceptionIndex;
struct GCounter
{
static int counter; // used static to guarantee compile time initialization
static int NewValue() {return counter++;}
};
#define TEST_THROW_EXCEPTION \
static int myConst = GCounter::NewValue();\
if(g_testThrowExceptionIndex == myConst)\
{\
g_testThrowExceptionIndex++;\
throw 0;\
}
#else
#define TEST_THROW_EXCEPTION
#endif
In main.cpp:
#if defined(_DEBUG) && defined(_EXCEPTION_TEST)
int g_testThrowExceptionIndex= 0;
int GCounter::counter= 0;
#endif
Then you can put "TEST_THROW_EXCEPTION" in any of your try/catch block you want to test out.
You cannot do this using preprocessor, as each compile unit is preprocessed separately. A run time solution is needed for this. You may create a global singleton and each place which requires a unique identifier can define a static int using this singleton.
struct GCounter
{
static int counter; // used static to guarantee compile time initialization
static int NewValue() {return counter++;}
};
int GCounter::counter = 0;
void Foo1()
{
static int ID1 = GCounter::NewValue();
}
void Foo2()
{
static int ID2 = GCounter::NewValue();
}
Note: the order of initialization of those static values (IDs) in multiple compilation units is not defined. You can be sure they will be always unique, but you cannot rely upon them having some particular values or ordering. Therefore be careful when e.g. saving them into a file - you should translate them to some neutral representation for that.
Seeing as you are using MSVC, you can always add a pre-build step that parses over the files and expands __COUNTER__ to a super global value instead of a unit global value. Of course the hard part is managing the files so as not to cause problems...
Related
I'm trying to write a production test software for an embedded system where I could write a single test script (which ideally is just C++ code), where parts are executed on the host computer and part on the DUT (Device Under Test). Communication is through a serial port.
One important goal here is to reduce code size on the embedded side, without reducing readability of the test output. So my level 0 objective, you could say a warmup exercise, is to be able to write something like this:
//TestScript.cpp
START_TESTS()
...
const unsigned pot1res = testPotentiometer(pot1);
TEST_PRINT("Potentiometer 1 test result %u", pot1res);
const unsigned pot2res = testPotentiometer(pot2);
TEST_PRINT("Potentiometer 2 test result %u", pot2res);
...
END_TESTS()
which would compile through preprocessor trickery and selective compilation on the embedded side to
const unsigned pot1res = testPotentiometer(pot1);
write_uart(123); //Unique id, perhaps from __COUNTER__
write_uart(pot1res);
const unsigned pot2res = testPotentiometer(pot2);
write_uart(124); //Unique id, perhaps from __COUNTER__
write_uart(pot2res);
and on the host
std::array gTestStrings = {
... other strings ....
TestString{123, "Potentiometer 1 test result %u", unsigned_tag},
TestString{124, "Potentiometer 2 test result %u", unsigned_tag},
... more strings ....
};
The purpose of the latter is then of course that the host software simply listens to the UART for the unique id's, then looks up the needed parameters from gTestStrings, receives them, and prints out the message to its test log. Note that the strings have disappeared entirely from the embedded side.
The embedded side here is of course easy, just define the TEST_PRINT macro in the obvious way, and supporting varargs etc shouldn't be too difficult. However, it's not clear how define the host side, since the code in between the macros has to disappear entirely. I'm pretty sure I can deal with getting the unsigned_tags etc correctly with some templates etc.
Standard C++17 is appreciated, but GCC/Clang specifics are allowed if needed, the preprocessor will obviously play heavily into this etc. The syntax of the macros can of course also be adjusted where necessary.
On the basis of "use templates to do the same thing with different types" you could simply define a templated class or method which invoke different implementations according to whether in the embedded context or host context.
Pseudocode example:
#include <sstream>
#include <string>
class Mock
{
protected:
// TODO : output values array / map - by - testID
public:
unsigned readPot(int const testID)
{
// TODO : return value from the values array/map
}
};
class ActualDevice
{
public:
unsigned readPot(int const testID)
{
// TODO : write/read the device
}
};
//DEVICE_IMPL must implement a method with this signature:
//unsigned readPot(int const testID)
template<typename DEVICE_IMPL>
void runTests()
{
DEVICE_IMPL device;
std::string testOutput;
//TODO : substitute with for-loop to run all tests
int testID = 1;
{
unsigned output = device.readPot(testID);
std::stringstream accum;
accum << "Test " << testID << " output = " << (int)output << std::endl;
testOutput = accum.str();
// TODO : do something with testOutput
}
}
void testHost ()
{
runTests<Mock>();
}
void testDevice()
{
runTests<ActualDevice>();
}
#ifdef __linux__ // or whatever you have there
#define START_TESTS() std::array gTestStrings = {
#define END_TESTS() };
#define TEST(expr, str) TestString{__LINE__, str, unsigned_tag},
#else
#define START_TESTS() {
#define END_TESTS() }
#define TEST(expr, ...) do{ \
const auto _val = (expr); \
write_uart(__LINE__); \
write_uart(_val); \
} while(0)
#endif
int main() {
START_TESTS()
TEST(testPotentiometer(pot1), "Potentiometer 1 test result %u");
TEST(testPotentiometer(pot2), "Potentiometer 2 test result %u");
END_TESTS()
}
I do not particularly like that design - seems not flexible enough for me. But such code could serve as a template for you to write something better. I added the expression inside the TEST macro - that way it can be removed on the host side, and used on the device side.
Another option could be X-macros:
pot_tests.h
X(123, pot1, "Potentiometer 1 test result %u")
X(124, pot2, "Potentiometer 2 test result %u")
embedded.c
START_TESTS()
...
#define X(id, pot, text) \
do { \
const unsigned potres = testPotentiometer(pot); \
write_uart(id); \
write_uart(potres); \
TEST_PRINT(text, potres); \
} while(0);
#include "pot_tests.h"
#undef X
...
END_TESTS()
host.cpp
std::array gTestStrings = {
... other strings ....
#define X(id, pot, text) TestString{id, text, unsigned_tag},
#include "pot_tests.h"
#undef X
... more strings ....
};
How can I use macros as function pointers? I have no idea to solve this. I created a sketch (doesn't work, full of syntax errors) to show what I try to accomplish. Please help!
#define D0_OUT(x) (x/1024*100) //I want to use this for Pin0 calculation
#define D1_OUT(x) (x*1024) //I want to use this for Pin1 calculation
struct Pin {
CalcMethod *calcMethod; //int methodName(int x) { return MACRO(x); }
Pin(CalcMethod *calcMethodParam) {
calcMethod = calcMethodParam;
}
int calc(int x) {
return calcMethod(x);
}
};
#define PIN_COUNT 2
Pin *pins[PIN_COUNT];
void start() {
pins[0] = new Pin(D0_OUT); //use the D0_OUT macro to calculate
pins[1] = new Pin(D1_OUT); //use the D1_OUT macro to calculate
int pin0CalcResult=pins[0]->calc(5); // =5/1024*100
int pin1CalcResult=pins[1]->calc(6); // =6*1024
}
Macros are handled by the preprocessor. They don't exist in the compiled code, therefore there is no pointer.
There is one rule you should follow in modern code and that rule is "don't use macros for furnctions". Macros for functions are a relict that still has some good uses but they are very rare.
Just declare a normal function
int do_out(int x) {
return x / 1024 * 100;
}
Also see "static const" vs "#define" vs "enum"
You can, but not advisable, use macros as named lambdas. Thus
#define D0_OUT [](int x) { return x / 1024 * 100; }
#define D1_OUT [](auto x) { return x * 1024; }
and it should work.
D0_OUT example usable in C++11 and D1_OUT usable with C++14.
I know this is an old thread..
Assuming that you cannot just change the macro to be a function. Maybe it is part of a driver of library somewhere and you need to pass it into another function for some reason like unit testing. You can just wrap the macro within your .c file where you want to use it.
So this:
#define D0_OUT(x) (x/1024*100) //I want to use this for Pin0 calculation
becomes:
static int D0_OUT_wrapper(int x)
{
return D0_OUT(x);
}
So wrapper goes in like normal:
pins[0] = new Pin(D0_OUT_wrapper);
If you have full control of the code you are writing then just don't use macros.
Let's say I have this code:
int function(bool b)
{
// execution path 1
int ret = 0;
if(b)
{
// execution path 2
ret = 55;
}
else
{
// execution path 3
ret = 120;
}
return ret;
}
I need some sort of a mechanism to make sure that the code has gone in any possible path, i.e execution paths 1, 2 & 3 in the code above.
I thought about having a global function, vector and a macro.
This macro would simply call that function, passing as parameters the source file name and the line of code, and that function would mark that as "checked", by inserting to the vector the info that the macro passed.
The problem is that I will not see anything about paths that did not "check".
Any idea how do I do this? How to "register" a line of code at compile-time, so in run-time I can see that it didn't "check" yet?
I hope I'm clear.
Usually coverage utilities (such as gcov) are supplied with compiler. However please note that they will usually give you only C0 coverage. I.e.
C0 - every line is executed at least once. Please note that a ? b : c is marked as executed even if only one branch have been used.
C1 - every branch is executed at least once.
C2 - every path is executed at least once
So even if your tests shows 100% C0 coverage you may not catch every path in code - and probably you don't have time to do it (number of paths grows exponentially with respect to branches). However it is good to know if you have 10% C2 or 70% C2 (or 0.1% C2).
Quite often there will be a utility supplied with your compiler to do this sort of code coverage analysis. For example, GCC has the gcov utility.
You need a code coverage program (gcov, bullseye, dev partner) and unit-testing (unittest++, cppunit, etc.). You write test that will test that function.
TEST( UnitTestFunction )
{
CHECK( function(true) == 55 );
CHECK( function(false) == 120 );
}
Then unit tests in this case do not just check for integrity (though they still do) but they also test for coverage.
Try SD C++ TestCoverage for a VisualStudio compatible test coverage tool. I believe that it in fact actually will tell you about test coverage of a?b:c, too.
The problem is that I will not see anything about paths that did not "check".
If this means in other words that you're not only looking for the set of code points which are actually executed but also for the set of code points which have been "marked" somehow as expected to be executed to maybe finally report the difference, i might have a very dangerous solution. It works for me on MSVC 2010 and 2013.
The approach is to make use of the pre program start initialization of static variables, but since all code points are in functions and therefore, the "static anker point" has to be put there somehow and so, the c++ feature of delayed initialization of static function variables has to be overcome.
This seems to be possible by adding an indirection through a template class (X) with a static member variable (progloc_) to enforce the initialization per template parameter which in turn is a wrapper struct which transports the needed information (_.FILE._ " at line " _.LINE._).
Putting this together, the most important code to achieve this could look like the following:
template <class T> class X {
public:
static T progloc_;
};
template <class T> T X<T>::progloc_;
#define TRACE_CODE_POINT \
struct ProgLocation { \
public: \
std::string loc_; \
ProgLocation() : loc_(std::string(__FILE__ " at line " S__LINE__)) \
{ \
TestFw::CodePoints::Test::imHere(loc_); \
} \
}; \
TestFw::CodePoints::X<ProgLocation> dummy; \
TestFw::CodePoints::Test::iGotCalled(dummy.progloc_.loc_);
The S__LINE__ - trick which is used in the ProgLocation - ctor comes from here on SO.
#define S(x) #x
#define S_(x) S(x)
#define S__LINE__ S_(__LINE__)
To track, the following is used:
class Test
{
private:
typedef std::set<std::string> TFuncs;
static TFuncs registeredFunctions;
static TFuncs calledFunctions;
public:
static int imHere(const std::string fileAndLine)
{
assert(registeredFunctions.find(fileAndLine) == registeredFunctions.end());
registeredFunctions.insert(fileAndLine);
return 0;
}
static void iGotCalled(const std::string fileAndLine)
{
if (calledFunctions.find(fileAndLine) == calledFunctions.end())
calledFunctions.insert(fileAndLine);
}
static void report()
{
for (TFuncs::const_iterator rfIt = registeredFunctions.begin(); rfIt != registeredFunctions.end(); ++rfIt)
if (calledFunctions.find(*rfIt) == calledFunctions.end())
std::cout << (*rfIt) << " didn't get called" << std::endl;
}
};
Maybe there are many problems connected with this approach which I don't see yet and make it inpracticable for your case, and as others pointed out, using static code analysis tools is for most situations the better solution.
EDIT:
Just found out that the provided solution has been discussed before in another context:
non-deferred-static-member-initialization-for-templates-in-gcc
You can use FILE and LINE preprocessor directives:
#define TRACE(msg) MyTraceNotify(msg,__FILE__,__LINE__)
Just insert TRACE(msg) macro in your code at the places you want to track, with your custom message, and write your MyTraceNotify function.
void MyTraceNotify(const char *msg, const char *filename, ULONG line)
{
/* Put your code here... */
}
i'd like to write a wrapper for a C++ framework. this framework is kinda buggy and not really nice and in C++. so i'd like to be able to call their methods from outside (via good old C file) of their framework by using just one shared lib. this sounds like the need for a wrapper that encapsulates the wanted framework methods for usage with C instead of C++.
So far so good.... here is what i already did:
interface aldebaran.h
(this is in my include folder, the ultrasound methods should be called from outside of the framework):
#ifndef _ALDEBARAN_H
#define _ALDEBARAN_H
#ifdef __cplusplus
extern "C" {
#endif
void subscribe_ultrasound();
void unsubscribe_ultrasound();
float read_ultrasound();
#ifdef __cplusplus
}
#endif
#endif
now the wrapper:
cpp file aldebaran.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aldebaran.h"
#include "alproxy.h"
#include "../../include/aldebaran.h"
/*
* Ultrasound defines
*/
#define ULTRASOUND_RESERVATION_MAGIC "magic_foobar"
#define ULTRASOUND_POLL_TIME 250
#define ULTRASOUND_READ_ATTEMPTS 50
#define ULTRASOUND_SLEEP_TIME 20
using namespace std;
using namespace AL;
/*
* Framework proxies
*/
ALPtr<ALProxy> al_tts;
ALPtr<ALProxy> al_led;
ALPtr<ALProxy> al_motion;
ALPtr<ALProxy> al_mem;
ALPtr<ALProxy> al_us;
ALPtr<ALProxy> al_cam;
ALPtr<ALProxy> al_dcm;
/*
* Constructor
*/
Aldebaran::Aldebaran(ALPtr<ALBroker> pBroker, std::string pName): ALModule(pBroker, pName)
{
try {
al_tts = this->getParentBroker()->getProxy("ALTextToSpeech");
al_led = this->getParentBroker()->getProxy("ALLeds");
al_motion = this->getParentBroker()->getProxy("ALMotion");
al_mem = this->getParentBroker()->getProxy("ALMemory");
al_us = this->getParentBroker()->getProxy("ALUltraSound");
al_cam = this->getParentBroker()->getProxy("NaoCam");
al_dcm = this->getParentBroker()->getProxy("DCM");
}catch(ALError& err){
std::cout << "XXX: ERROR: " << err.toString() << std::endl;
return 1;
}
printf("XXX: module aldebaran initiated\n");
fflush(0);
}
/*
* Destructor
*/
Aldebaran::~Aldebaran()
{
printf("XXX: module aldebaran destructed\n");
fflush(0);
}
/*
* Subscribe to ultrasound module
*/
void subscribe_ultrasound()
{
ALValue param;
param.arrayPush(ULTRASOUND_POLL_TIME);
al_us->callVoid("subscribe", string(ULTRASOUND_RESERVATION_MAGIC), param);
printf("XXX: ultrasound subscribed: %s\n", ULTRASOUND_RESERVATION_MAGIC);
fflush(0);
}
/*
* Unsubscribe to ultrasound module
*/
void unsubscribe_ultrasound()
{
al_us->callVoid("unsubscribe", string(ULTRASOUND_RESERVATION_MAGIC));
printf("XXX: ultrasound unsubscribed: %s\n", ULTRASOUND_RESERVATION_MAGIC);
fflush(0);
}
/*
* Read from ultrasound module
*/
float read_ultrasound()
{
int i;
float val1, val2;
float val_sum;
ALValue distance;
val_sum = .0f;
for(i = 0; i < ULTRASOUND_READ_ATTEMPTS; ++i){
SleepMs(ULTRASOUND_SLEEP_TIME);
distance = al_mem->call<ALValue>("getData", string("extractors/alultrasound/distances"));
sscanf(distance.toString(AL::VerbosityMini).c_str(),"[%f, %f, \"object\"]", &val1, &val2);
val_sum += val1;
}
return val_sum / (1.f * ULTRASOUND_READ_ATTEMPTS);
}
definition file for aldebaran.cpp:
#ifndef ALDEBARAN_API_H
#define ALDEBARAN_API_H
#include <string>
#include "al_starter.h"
#include "alptr.h"
using namespace AL;
class Aldebaran : public AL::ALModule
{
public:
Aldebaran(ALPtr<ALBroker> pBroker, std::string pName);
virtual ~Aldebaran();
std::string version(){ return ALTOOLS_VERSION( ALDEBARAN ); };
bool innerTest(){ return true; };
};
#endif
So this should be a simple example for my wrapper and it compiles fine to libaldebaran.so.
now my test program in C:
... now i'd like to call the interface aldebaran.h methods from a simple c file like this:
#include <stdio.h>
/*
* Begin your includes here...
*/
#include "../include/aldebaran.h"
/*
* End your includes here...
*/
#define TEST_OKAY 1
#define TEST_FAILED 0
#define TEST_NAME "test_libaldebaran"
unsigned int count_all = 0;
unsigned int count_ok = 0;
const char *__test_print(int x)
{
count_all++;
if(x == 1){
count_ok++;
return "ok";
}
return "failed";
}
/*
* Begin tests here...
*/
int test_subscribe_ultrasound()
{
subscribe_ultrasound();
return TEST_OKAY;
}
int test_unsubscribe_ultrasound()
{
unsubscribe_ultrasound();
return TEST_OKAY;
}
int test_read_ultrasound()
{
float i;
i = read_ultrasound();
return (i > .0f ? TEST_OKAY : TEST_FAILED);
}
/*
* Execute tests here...
*/
int main(int argc, char **argv)
{
printf("running test: %s\n\n", TEST_NAME);
printf("test_subscribe_ultrasound: \t %s\n", __test_print(test_subscribe_ultrasound()));
printf("test_read_ultrasound: \t %s\n", __test_print(test_read_ultrasound()));
printf("test_unsubscribe_ultrasound: \t %s\n", __test_print(test_unsubscribe_ultrasound()));
printf("test finished: %s has %u / %u tests passed\n\n", TEST_NAME, count_ok, count_all);
return (count_all - count_ok);
}
how can i manage to call these methods? i mean within my C file i have no possibility to create such an object-instance (that generated all the needed ALProxies), have i?
help would be really appreciated... thx
thank you very much so far!!
as xtofl said.. i'd like to keep my interface as simple as possible (without another c++ object preferably):
#ifndef _ALDEBARAN_H
#define _ALDEBARAN_H
#ifdef __cplusplus
extern "C" {
#endif
void subscribe_ultrasound();
void unsubscribe_ultrasound();
float read_ultrasound();
#ifdef __cplusplus
}
#endif
#endif
the problem hereby is that functions like subscribe_ultrasound() cannot be called without the instanciation of all the proxies... this is our precondition:
...
al_tts = this->getParentBroker()->getProxy("ALTextToSpeech");
al_led = this->getParentBroker()->getProxy("ALLeds");
al_motion = this->getParentBroker()->getProxy("ALMotion");
al_mem = this->getParentBroker()->getProxy("ALMemory");
al_us = this->getParentBroker()->getProxy("ALUltraSound");
al_cam = this->getParentBroker()->getProxy("NaoCam");
al_dcm = this->getParentBroker()->getProxy("DCM");
...
if i don't have the code above called, all other will fail.
within their framework it is possible to "autoload" my libaldebaran.so via a python script like this call:
myModule = ALProxy("Aldebaran", global_params.strRemoteIP, global_params.nRemotePort );
The framework log then says:
May 10 15:02:44 Hunter user.notice root: XXX: module aldebaran initiated
May 10 15:02:46 Hunter user.notice root: INFO: Registering module : 'Aldebaran'
May 10 15:02:46 Hunter user.notice root: ______ End of loading libraries ______
which is totally okay... it called the constructor of my module (so all other needed proxies got instanciated too).
but of course this instance does not belong to my C program...
maybe there is a possibility to share this to all other processes?
You might want to take a slightly different approach. Consider something like this for your C interface:
#ifdef __cplusplus
extern "C" {
#endif
struct UltrasoundHandle;
UltrasoundHandle* ultrasound_Create();
void ultrasound_Destroy(UltrasoundHandle *self):
void ultrasound_Subscribe(UltrasoundHandle *self);
void ultrasound_Unsubscribe(UltrasoundHandle *self);
float ultrasound_Read(UltrasoundHandle *self);
#ifdef __cplusplus
}
#endif
The UltrasoundHandle structure is purposefully opaque so that you can define it in the implementation to be whatever you want it to be. The other modification that I made was to add explicit creation and destruction methods akin to the constructor and destructor. The implementation would look something like:
extern "C" {
struct UltrasoundHandle {
UltrasoundHandle() {
// do per instance initializations here
}
~UltrasoundHandle() {
// do per instance cleanup here
}
void subscribe() {
}
void unsubscribe() {
}
float read() {
}
};
static int HandleCounter = 0;
UltrasoundHandle* ultrasound_Create() {
try {
if (HandleCounter++ == 1) {
// perform global initializations here
}
return new UltrasoundHandle;
} catch (...) {
// log error
}
return NULL;
}
void ultrasound_Destroy(UltrasoundHandle *self) {
try {
delete self;
if (--HandleCounter == 0) {
// perform global teardown here
}
} catch (...) {
// log error
}
}
The key is to wrapping C++ interfaces for C is to expose the OO concepts through free functions where the caller explicitly passes the object pointer (this) to the function and to explicitly expose the constructor and destructor in the same manner. The wrapper code can be almost mechanically generated from there. The other key points are that you never let exceptions propagate outward and steer clear of global object instances. I'm not sure if the latter will cause you grief, but I would be concerned about construction/destruction ordering problems.
You said yourself to create a C wrapper API around an OO framework.
This means you don't need any objects passing the wrapper API (as it appears from the decribed header). It seems all objects needed are created/destructed behind the wrapper API, out of view of your test program.
The first seems the case. You don't need objects to test your wrapper API. In the end, all objects are bytes (in memory) that are accessed through a fixed set of functions. It doesn't matter much whether the functions are written as member-functions (C++) or as plain C functions, as long as they obey the intended semantics of your objects.
I'm not clear whether you're aware of this, but if you have C++ code to dynamically load into your program, then you should link your program with the C++ compiler and make your main function a C++ function too - even if it is as trivial as:
int main(int argc, char **argv)
{
return(real_main_in_c(argc, argv));
}
The real_main_in_c() function is what you previously called main(); it has simply been renamed. This ensures that the C++ mechanisms for handling initialization of global and static variables, etc, are loaded and operational. The C++ startup code does more work than the C startup code. Dynamically loading C
This is only one (small) facet of the answer - but it is an important practical one.
Keep things as simple as possible - but not simpler. I think you're trying to make it too simple here, wrap it all up but use the c++ compiler.
so, if you create your wrapper using the c++ compiler, you can instantiate the objects inside your subscribe function, release them all in the unsubscribe, all using static (or global) objects. The 3 functions you want to expose simple get wrapped with "extern C" and you have a C-style interface exposed to any caller, whilst still encapsulating C++ objects.
If you need another function to instantiate all the proxies, add one; alternatively if they don't already exist, create them so they'll always be created in the first call to subscribe.
Now, if you need the proxy objects on a per-instance basis (ie you have 2 callers who both want to subscribe, and need a unique proxy per caller), then you'll have to store the objects in a collection (I suggest a map), every call you make must then pass in a 'handle' or 'sessionid' that you use to extract the per-call objects from the map.
I'm creating a macro in C++ that declares a variable and assigns some value to it. Depending on how the macro is used, the second occurrence of the macro can override the value of the first variable. For instance:
#define MY_MACRO int my_variable_[random-number-here] = getCurrentTime();
The other motivation to use that is to avoid selecting certain name to the variable so that it be the same as a name eventually chosen by the developer using the macro.
Is there a way to generate random variable names inside a macro in C++?
-- Edit --
I mean unique but also random once I can use my macro twice in a block and in this case it will generate something like:
int unique_variable_name;
...
int unique_variable_name;
In this case, to be unique both variable names have to be random generated.
Try the following:
// One level of macro indirection is required in order to resolve __COUNTER__,
// and get varname1 instead of varname__COUNTER__.
#define CONCAT(a, b) CONCAT_INNER(a, b)
#define CONCAT_INNER(a, b) a ## b
#define UNIQUE_NAME(base) CONCAT(base, __COUNTER__)
void main() {
int UNIQUE_NAME(foo) = 123; // int foo0 = 123;
std::cout << foo0; // prints "123"
}
__COUNTER__ may have portability issues. If this is a problem, you can use __LINE__ instead and as long as you aren't calling the macro more than once per line or sharing the names across compilation units, you will be just fine.
use __COUNTER__ (works on gcc4.8, clang 3.5 and Intel icc v13, MSVC 2015)
#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)
#define uniquename static bool CONCAT(sb_, __COUNTER__) = false
Add M4 to your build flow? This macro language has some stateful capabilities, and can successfully be intermingled with CPP macros. This is probably not a standard way to generate unique names in a C environment, though I've been able to sucessfully use it in such a manner.
You probably do not not want random, BTW, based on the way you posed your question. You want unique.
You could use __FILE__ and __LINE__ in the macro expansion to get you the uniqueness you seem to be going for... those metavariables get defined within the source file context, so be careful to make sure you get what you are looking for (e.g., perils of more than one macro on the same line).
Generating unique names in the preprocessor is difficult. The closest you can get is to mangle __FILE__ and __LINE__ into the symbol as popcnt suggests. If you really need to generate unique global symbol names, then I would follow his suggestion about using something like M4 or a Perl script in your build system instead.
You might not need unique names. If your macro can impose a new scope, then you can use the same name since it will simply shadow other definitions. I usually follow the common advice of wrapping macros in do { ... } while (0) loops. This only works for macros which are statements - not expressions. The macro can update variables using output parameters. For example:
#define CALC_TIME_SINCE(t0, OUT) do { \
std::time_t _tNow = std::time(NULL); \
(OUT) = _tNow - (t0); \
} while (0)
If you follow a few rules, you are usually pretty safe:
Use leading underscores or similar naming conventions for symbols defined within the macro. This will prevent problems associated with a parameter using the same symbol from occurring.
Only use the input parameters once and always surround them with parentheses. This is the only way to make macros work with expressions as input.
Use the do { ... } while (0) idiom to ensure that the macro is only used as a statement and to avoid other textual replacement problems.
Instead of having the preprocesser create a name, you could possibly let the macro user give you a name.
#define MY_MACRO(varname) int varname = getCurrentTime();
I needed something similar for a case where I didn't have any profiling tools, but I wanted to count how many threads were inside a particular block of code as well as the amount of time (ticks) spent in that block of code by each thread, In this case every block needed a unique static variable accessible to all threads, and I needed to later reference that variable to incr (I used a logging API rather than printf in the actual code, but this works as well). At first I thought I was very clever by doing the following:
#define PROF_START { \
static volatile int entry_count##___FUNCTION__##__LINE__ = 0; int *ptc = &entry_count##___FUNCTION__##__LINE__; \
clock_t start, end; \
start = times(0); \
(*ptc)++;
But then I realized this is just silly and the C compiler will simply do this for you, as long as each "static" declaration is its own block:
#include <stdio.h>
#include <sys/times.h>
#define PROF_START { \
static int entry_count = 0; \
clock_t start, end; \
start = times(0); \
entry_count++;
#define PROF_END \
end = times(0); \
printf("[%s:%d] TIMER: %ld:%d\n" , __FUNCTION__, __LINE__, end-start, entry_count); \
entry_count--; \
}
Note the open/close brackets in each macro. This isn't strictly thread-safe, but for my profiling purposes I could assume the incr and decr operations were atomic. Here's a recursion sample which uses the macros
#define ITEM_COUNT 5
struct node {
int data;
struct node *next;
};
revsort(struct node **head)
{
struct node *current = *head;
struct node *next_item;
while (current->next)
{
PROF_START
next_item = current->next;
current->next = next_item->next;
next_item->next = *head;
*head = next_item;
PROF_END
}
}
rrevsort(struct node **head)
{
struct node *current = *head;
struct node *next_item = current->next;
PROF_START
current->next = 0;
if (next_item)
{
*head = next_item;
rrevsort(head);
next_item->next = current;
}
PROF_END
}
printnode(struct node *head)
{
if (head)
{
printf("%d ", head->data);
printnode(head->next);
}
else
printf("\n");
}
main()
{
struct node node_list[ITEM_COUNT];
struct node *head = &node_list[0];
int i;
for (i=0; i < ITEM_COUNT - 1; i++)
{
PROF_START
node_list[i].data = i;
node_list[i].next = &node_list[i+1];
PROF_END
}
node_list[i].data = i;
node_list[i].next = 0;
printf("before\n");
printnode(head);
revsort(&head);
printf("after\n");
printnode(head);
rrevsort(&head);
printf("before\n");
printnode(head);
}
Extra hint, the above program is a common interview question. Excerpt from "nm -A":
macro:0804a034 b entry_count.1715
macro:0804a030 b entry_count.1739
macro:0804a028 b entry_count.1768
macro:0804a02c b entry_count.1775
Here is a succinct macro definition to generate the singleton pattern above.
#define SINGLETON_IMPLIMENTATION(CLASS_NAME) static CLASS_NAME *g##CLASS_NAME = nil; + (CLASS_NAME *)instance { #synchronized(self) { if (g##CLASS_NAME == nil) g##CLASS_NAME = [self new]; } return g##CLASS_NAME; }
#define SINGLETON_DECLARATION(CLASS_NAME) + (CLASS_NAME *)instance;
While I don't think its even possible, you should seriously consider making a class out of this.
If you want a random element in a random array to hold a certain value, you can do this:
std::vector< std::vector<int> > m_vec;
Then wrap it in a class, so the developer can only set a number:
void set(int foo)
{
m_vec[random()][random()] = foo;
}
Is there any reason why you want it a macro? Random variable name sounds dangerous, what if it picks something already defined somewhere else in the code?