静态库命名空间内简单函数的编译错误

Posted

技术标签:

【中文标题】静态库命名空间内简单函数的编译错误【英文标题】:Compile error for simple function inside of namespace in static library 【发布时间】:2013-03-21 11:31:48 【问题描述】:

我遇到了一个奇怪的挑战:我的静态库构建并且可以在没有这些日志记录功能的情况下使用,但是当我包含它们时,我无法编译包含 dove.h 的代码,然后链接到 libdove.a。我最初将所有日志函数移到了 dove 命名空间之外,并在 dove.cpp 中声明/定义了它们,这很有效。 但是,它泄漏了函数签名,我想在 一个独立的项目。

鸽子.h:

namespace dove 
  /* Many functions and classes */

  void log(const char* msg, int level); 
  void info(const char* msg);                                                                                                 
  void error(const char* msg);
  void debug(const char* msg);

鸽子.cpp:

void dove::log(const char* msg, int level) 
  if (level <= LOG_LEVEL)
    std::cout << "dove: " << msg << std::endl;


void dove::info(const char* msg)  log(msg, LOG_INFO); 
void dove::error(const char* msg)  log(msg, LOG_ERROR); 
void dove::debug(const char* msg)  log(msg, LOG_DEBUG); 

鸽子 Makefile 部分:

all:                                                                                                                            
  $(CXX) -c $(CFLAGS) $(INC) -o dove.o dove.cpp
  ar rvs libdove.a dove.o      
  ranlib libdove.a

所有这些都构建得很好!我得到了 libdove.a,一切似乎都很开心。但是,当我在另一个项目中有一行 #include "dove.h" 时,我在 dove.h 上收到以下编译错误:

make[1]: Entering directory `<omitted>/dove'
g++ -c -g  -Ilibs/rapidxml-1.13 -o dove.o dove.cpp
ar rvs libdove.a dove.o
ar: creating libdove.a
a - dove.o
ranlib libdove.a
make[1]: Leaving directory `<omitted>/dove'
cd <omitted> && make
make[1]: Entering directory `<omitted>'
g++  -g  -c -o build/graph.o src/utils/graph.cpp
g++  -g  -c -o build/util.o src/utils/util.cpp
g++ -g  -I<omitted>/dove -Isrc/utils -c -o build/mps.o src/mps.cpp 
In file included from src/mps.cpp:13:
<omitted>/dove/dove.h:247: error: expected ‘,’ or ‘...’ before string constant
<omitted>/dove/dove.h:250: error: expected ‘,’ or ‘...’ before string constant
make[1]: *** [bin/hybrid] Error 1

这些错误总是发生在日志和调试中。永远不要在信息和错误上。我已将它们放置在鸽子命名空间中的多个位置(顶部、中间、分隔声明、底部),这两个总是在抱怨。

子项目的Makefile:

# Contains libdove.a
DOVE_ROOT    ?= $(CURDIR)/../../dove
LIBS         := -L$(DOVE_ROOT) -ldove
INC          := -I$(DOVE_ROOT) -Isrc/utils                                                                                      
CXXFLAGS     += -g  

all: $(util_o)
  $(CXX) $(CXXFLAGS) $(INC) -c -o build/mps.o src/mps.cpp 
  $(CXX) $(CXXFLAGS) -o bin/hybrid build/*.o $(LIBS)

【问题讨论】:

dove.h 第 247 行包含什么? 它包含void log(const char* msg, int level);。第二个错误在包含void debug(const char* msg); 的行上。我总是得到两个编译错误,而且总是在这两个函数上 我敢打赌这里涉及“宏观魔术”。它说“预期的,或...在字符串常量之前”,但该行没有字符串常量。这告诉我logdebug 可能被翻译成字符串常量(或包含字符串常量的东西)。尝试将名称更改为 xlogxdebug 只是为了澄清这是问题所在。 你怎么知道的!?这让我慢了好几天!使用 x 前缀的名称解决了所有错误 发布答案,我会接受 btw 【参考方案1】:

按照原问题的cmets,似乎某些宏与相关代码中使用的函数名称之间存在冲突。

这可以通过错误消息对实际代码行没有意义这一事实来确定 - 相关行中没有“字符串常量”。

解决方法是针对#undef log#undef debug,或者为宏或函数使用不同的名称。

[另一个不使用小写宏名的论据!]

【讨论】:

我正在使用 -E 标志,看看我是否能发现真正的问题,但到目前为止还没有运气 顺便说一句:切换到更明智的日志记录“框架”似乎是个好主意 ;-)

以上是关于静态库命名空间内简单函数的编译错误的主要内容,如果未能解决你的问题,请参考以下文章

如果 MFC RUNTIME_CLASS 参数具有命名空间,则编译器错误

C ++中的编译错误可能是命名空间问题

WebAssembly 编译器错误:使用外部库编译时未定义符号

尝试编译时未找到名称空间错误

flash里的编译器错误是啥意思啊?

dll导出命名空间下的c风格函数陷阱