Correct use of variable argument functions C API with C++ implementation

I want to use a C++ logging library in a mixed C/C++ application. The legacy application is full of printf style logging. The new library also supports that.

The C files are compiled with C compiler, so I am not able to include C++ logging headers into them.

I am struggling to create a C++ library with C-style headers and C++ source file:

//logger.h
extern "C" {
    extern void RS_LOG_INFO_PRIVATE(const char* fmt, ...);
    #define LOG_INFO(...)  RS_LOG_INFO_PRIVATE(__VA_ARGS__)
}

//logger.cpp
#include "logger.h"
#include <aws/core/utils/logging/LogMacros.h>
#include <utility>
template<class... Args>
void RS_LOG_INFO_PRIVATE(const char* fmt, Args&&... args) {    
    AWS_LOG_DEBUG(fmt, std::forward<Args>(args)...);
}

//main file
#include "logger.h"

int main() {
    LOG_INFO("test %s", "me");
}

I get undefined reference to 'RS_LOG_INFO_PRIVATE'.

nm -C also verifies this:

U RS_LOG_INFO_PRIVATE(char const*, ...) 

Is there a solution to solve this, or I should change my approach?

  • 2

    extern "C" void RS_LOG_INFO_PRIVATE(const char* fmt, ...); and template<class... Args> void RS_LOG_INFO_PRIVATE(const char* fmt, Args&&... args) are not the same. C-style ... varargs are not C++ Args&&....

    – 




  • If you can avoid variadic functions then do so. They are one of the biggest design flaws of C and should never have been invented in the first place.

    – 

  • 5

    I sense a massive misunderstanding of C++ templates.. try reading this first: Why can templates only be implemented in the header file?

    – 

  • @Lundin That’s not likely to be feasible given “The legacy application is full of printf style logging.”

    – 

  • 4

    In C, this ugliness is handled via the va_args hack, and C++ variadic templates have absolutely nothing to do, whatsoever, with that, and the two are two completely different and incompatible approaches, that work in fundamentally different ways. Stick to variadic templates for C++ and write a C-only hack that uses va_args.

    – 

Leave a Comment