【问题标题】:#ifdef is returning different values inside the same header file#ifdef 在同一个头文件中返回不同的值
【发布时间】:2020-11-14 03:59:56
【问题描述】:

我有两个 C++ 文件 main.cppclient.cpp,还有一个头文件 action.h。我正在尝试使用预处理器指令来模拟一个简单的客户端-服务器场景。代码如下:

//main.cpp
#include "action.h" 
extern void connect(); 
static Action server; 
int main()
{
    server.init(); 
    connect(); 
    server.execute(); 
    return 0; 
} 
//client.cpp
#define CLIENT 
#include "action.h" 
void connect()
{
    Action client; 
    client.init(); 
    client.execute(); 
}

还有头文件。

#include <iostream>
struct Action
{
    #ifdef CLIENT
    int data = 10;
    #else
    int data = 13; 
    #endif
    inline void init()
    {
        #ifdef CLIENT
        std::cout << "Client " << data << std::endl;
        data = -1;
        #else
        std::cout << "Server " << data << std::endl;
        data = 0;
        #endif
    }
    inline void execute()
    {
        #ifdef CLIENT
        std::cout << "Server is " << data << std::endl;
        #else
        std::cout << "Number of clients is " << data << std::endl;
        #endif
    } 
};

当我运行它时,我得到以下结果:

服务器 13

服务器 10

客户端数量为0

客户端数量为0

现在我的问题是为什么#ifdef CLIENT 块在action.h (int data = 10) 的声明部分执行,而#else 块在init()execute() 函数内执行,当我从@ 调用它们时987654334@文件?为什么不是所有三个调用都转到#ifdef 部分?

【问题讨论】:

  • 您的程序表现出未定义的行为,违反了One Definition Rule
  • Action有两个不同的定义违反了一个定义规则。程序的行为未定义。

标签: c++ preprocessor-directive


【解决方案1】:

此程序表现出未定义的行为。它违反了One Definition Rule (ODR)。具体这部分:

[basic.def.odr]/6 一个类类型可以有多个定义,... 带有外部链接的内联函数... 在程序中,只要每个定义都出现在不同的翻译单元中,并提供定义满足以下要求。给定这样一个名为D 的实体在多个翻译单元中定义,那么

(6.1) — D 的每个定义都应包含相同的标记序列...
...

如果D 的定义不满足这些要求,则行为未定义。

在你的例子中,你有两个类 Action 的定义以及它的内联成员函数 Action::initAction::execute,它们由不同的标记序列组成,这要归功于宏技巧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多