Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make sure different C++ code base using the same macro?

Tags:

c++

macros

We are working on two C++ code base, let's call it A and B, the A is an build as an library, and distribute the header files .h and .a file to B.

Let's say there is Lock.h file in A as following:

// Lock.h in code base A
class Lock {
    ... ...
#ifdef TRACK_THREAD_OWNER_FOR_DEBUG
    virtual int GetLockOwner();
#endif
    ... ...
private:
    CriticalSection section;
#ifdef TRACK_THREAD_OWNER_FOR_DEBUG
    int threadOwner;
#endif
};

// Caller.cc in code base B
#include "xxx/xxx/Lock.h"
Lock lockObject;
lockObject.Lock();

In code base A, we by default will enable TRACK_THREAD_OWNER_FOR_DEBUG and may change it just before final release day.

We hit some hard bug because TRACK_THREAD_OWNER_FOR_DEBUG are different in A and B, and cause memory corruption because the sizeof(Lock) is different in two library.

So how to protect from this error? Can we trigger an compiler error when build the caller.cc file if the build macro TRACK_THREAD_OWNER_FOR_DEBUG is different in two project?

like image 699
ZijingWu Avatar asked Aug 25 '17 03:08

ZijingWu


People also ask

How do you check if a macro is defined in C?

To check – A Macro is defined or not, we use #ifdef preprocessor directive. To check whether a Macro is defined or not in C language – we use #ifdef preprocessor directive, it is used to check Macros only. If MACRO_NAME is defined, then the compiler will compile //body (a set of statements written within the #ifdef ...

Can I use C libraries in C++?

If the C++ compiler provides its own versions of the C headers, the versions of those headers used by the C compiler must be compatible. Oracle Developer Studio C and C++ compilers use compatible headers, and use the same C runtime library. They are fully compatible.

Can I mix C and C++ code?

C and C++ are two closely related programming languages. Therefore, it may not come as a surprise to you that you can actually mix C and C++ code in a single program. However, this doesn't come automatically when you write your code the normal way.

What is __ Cplusplus in C++?

__cplusplus. This macro is defined when the C++ compiler is in use. You can use __cplusplus to test whether a header is compiled by a C compiler or a C++ compiler. This macro is similar to __STDC_VERSION__ , in that it expands to a version number.


1 Answers

It is not possible to make this into compiler error, however it should be possible to make this into reasonably clear linker error by exporting some symbol which name depends on the currently defined macros. For example using static guard variable:

//  Foo.hpp - library header file
#pragma once

class Foo
{
    public: Foo();
#ifdef IMPORTANT_CONDITION
    int m_field;
#endif
};

class ConditionGuard
{
    public:
    ConditionGuard(void) noexcept
    {
    #ifdef IMPORTANT_CONDITION
        CONDITION_ON();
    #else
        CONDITION_OFF();
    #endif
    }

#ifdef IMPORTANT_CONDITION
    private: static void CONDITION_ON(void);
#else
    private: static void CONDITION_OFF(void);
#endif
};

static ConditionGuard const condition_guard{};

// Foo.cpp - library implementation file 
#include "Foo.hpp"

Foo::Foo(void) {}

#ifdef IMPORTANT_CONDITION
void ConditionGuard::CONDITION_ON(void) {}
#else
void ConditionGuard::CONDITION_OFF(void) {}
#endif

Now when user code includes library header Foo.hpp it will also trigger construction of condition_guard static variable which will call a library function depending on condition being protected. So if there is a translation unit including Foo.hpp where IMPORTANT_CONDITION is defined differently than in compiled library then there will be a linker error for missing CONDITION_ON or CONDITION_OFF. CONDITION_ON and CONDITION_OFF function names should contain error text.

like image 91
user7860670 Avatar answered Sep 22 '22 21:09

user7860670