Linux 上 Poco::Logger 的编译器错误 - 函数声明被视为宏

Posted

技术标签:

【中文标题】Linux 上 Poco::Logger 的编译器错误 - 函数声明被视为宏【英文标题】:Compiler errors with Poco::Logger on Linux - function declaration treated as macro 【发布时间】:2014-07-14 12:03:52 【问题描述】:

我一直在尝试构建使用 Poco::Application 类作为其基础的可执行文件,但编译器给出了以下指向 Poco 代码的错误。

In file included from /home/mie/Poco/poco-1.4.6p4/Util/include/Poco/Util/Application.h:48:0,
                 from /home/mie/myproject/src/main.cpp:15:
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:152:59: error: macro "log" passed 3 arguments, but takes just 1
In file included from /home/mie/Poco/poco-1.4.6p4/Util/include/Poco/Util/Application.h:48:0,
                 from /home/mie/myproject/src/main.cpp:15:
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:427:58: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:428:86: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:601:72: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:610:100: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:621:30: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:627:42: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:633:33: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:639:45: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:645:30: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:651:42: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:657:32: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:663:44: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:669:31: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:675:43: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:681:36: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:687:48: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:693:30: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:699:42: error: macro "log" passed 4 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:705:30: error: macro "log" passed 2 arguments, but takes just 1
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:711:42: error: macro "log" passed 4 arguments, but takes just 1
In file included from /home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:44:0,
                 from /home/mie/Poco/poco-1.4.6p4/Util/include/Poco/Util/Application.h:48,
                 from /home/mie/myproject/src/main.cpp:15:
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Channel.h:75:15: error: expected unqualified-id before ‘__extension__’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Channel.h:75:15: error: expected ‘)’ before ‘__extension__’
In file included from /home/mie/Poco/poco-1.4.6p4/Util/include/Poco/Util/Application.h:48:0,
                 from /home/mie/myproject/src/main.cpp:15:
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:145:7: error: expected unqualified-id before ‘__extension__’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:145:7: error: expected ‘)’ before ‘__extension__’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:149:7: error: expected unqualified-id before ‘__extension__’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:149:7: error: expected ‘)’ before ‘__extension__’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:152:7: error: variable or field ‘log’ declared void
In file included from /home/mie/Poco/poco-1.4.6p4/Util/include/Poco/Util/Application.h:48:0,
                 from /home/mie/myproject/src/main.cpp:15:
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:427:7: error: variable or field ‘log’ declared void
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:428:7: error: variable or field ‘log’ declared void
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:601:21: error: variable or field ‘log’ declared void
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:601:21: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by default]
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:603:2: error: expected primary-expression before ‘if’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:603:2: error: expected ‘’ before ‘if’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:610:13: error: ‘Logger’ has not been declared
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:610:21: error: variable or field ‘log’ declared void
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:610:21: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by default]
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:612:2: error: expected primary-expression before ‘if’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:612:2: error: expected ‘’ before ‘if’
/home/mie/Poco/poco-1.4.6p4/Foundation/include/Poco/Logger.h:616:1: error: expected declaration before ‘’ token
make[2]: *** [CMakeFiles/app.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/app.dir/all] Error 2

在这里,我从我的主目录中包含了最新版本的 Poco (1.4.6p4),但我尝试了来自 CentOS 6.5 存储库的 1.4.2p1-2.el6,结果相同。在 OS X 上我没有这个问题(我相信那里的库版本是 1.4.2)。

如果我查看第 152 行 Poco/Logger.h 中的内容,第一个错误指向的位置,它似乎是一个函数声明,而不是错误状态的宏。

//
// Logger.h
//
// $Id: //poco/1.4/Foundation/include/Poco/Logger.h#5 $
//
// Library: Foundation
// Package: Logging
// Module:  Logger
//
// Definition of the Logger class.
... (comment continues)


#ifndef Foundation_Logger_INCLUDED
#define Foundation_Logger_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/Channel.h"
#include "Poco/Message.h"
#include "Poco/Format.h"
#include <map>
#include <vector>
#include <cstddef>


namespace Poco 


class Exception;


class Foundation_API Logger: public Channel
        /// Logger is a special Channel that acts as the main
        /// entry point into the logging framework.
    ... (comment continues)

public:
    ... (other declarations)

    void log(const Exception& exc, const char* file, int line);     <= line 152
                /// Logs the given exception with priority PRIO_ERROR.  
                ///
                /// File must be a static string, such as the value of
                /// the __FILE__ macro. The string is not copied
                /// internally for performance reasons.

    ... (and so on)

那么为什么我的编译器将此函数声明视为对宏的引用?

顺便说一句,我刚刚注释掉了在构建过程中早期的一个奇怪错误。也许这些是相关的。我尝试在内联函数中使用 tgmath.h 中的 fmod 函数,编译器在一行代码中给出了六次此错误:

/.../header.h:418: error: ”void*” is not a pointer-to-object type
/.../header.h:418: error: ”void*” is not a pointer-to-object type
/.../header.h:418: error: ”void*” is not a pointer-to-object type
/.../header.h:418: error: ”void*” is not a pointer-to-object type
/.../header.h:418: error: ”void*” is not a pointer-to-object type
/.../header.h:418: error: ”void*” is not a pointer-to-object type

这是触发错误的头文件中的代码:

inline void ProgressCounter::createTimeString(
    std::string& timeString,
    const long long& elapsedTotalS)

    short elapsedH = (short)elapsedTotalS / 3600;
    //short elapsedS = 0;
    short elapsedS = fmod(elapsedTotalS, 60);           <= error here
    short elapsedM = 0;
    //short elapsedM = fmod(elapsedTotalS - elapsedS, 3600) / 60;
    char timeCString[10];
    snprintf(timeCString, 10, "%02u:%02u:%02u", elapsedH, elapsedM, elapsedS);

    timeString = timeCString;

包含头文件 tgmath.h 并且代码在 OS X 上编译没有问题。我不明白错误中的 void* 指的是哪里。

我一直在 CentOS 6.5 上使用 GCC 4.4.7,在 Ubuntu 12.04 上使用 GCC 4.4.6.3-1ubuntu5。

【问题讨论】:

【参考方案1】:

&lt;math.h&gt;&lt;tgmath.h&gt; 定义了很多宏,包括与同名的任何东西冲突的 log 宏。

在 C++ 代码中,您应该包含 &lt;cmath&gt;&lt;ctgmath&gt;,其中类型泛型宏被 C++ 函数重载替换。

PS:至少对于 gcc,&lt;ctgmath&gt; 似乎需要 C++11 支持,所以你必须添加“-std=c++0x”或“-std=c++11”到编译选项。

【讨论】:

【参考方案2】:

首先尝试包含您的 POCO 库,看看是否有帮助。就在几天前,我在 Windows 上的 VS 2010 中遇到了一个问题,当我上次#included POCO 库时,许多 Windows API 突然变得未定义。将它们排在其他 #include 之前可以解决问题。

修复后,我没有深入分析究竟是什么项目导致了问题。

【讨论】:

以上是关于Linux 上 Poco::Logger 的编译器错误 - 函数声明被视为宏的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有编译器的 Linux 上安装 gcc

在 Windows 上运行并生成 Linux 代码的 C++ 编译器

快速了解Linux上gcc编译器

Windows 上适用于 Linux 的 C++ 编译器? [关闭]

Windows下怎样编译出可在Linux上执行的程序

如何在linux上安装fortran编译器