首页 > 解决方案 > #ifdef 在同一个头文件中返回不同的值

问题描述

我有两个 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)#elseinit()execute()client.cpp#ifdef

标签: c++preprocessor-directive

解决方案


该程序表现出未定义的行为。它违反了单一定义规则(ODR)。具体这部分:

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

(6.1) — 的每个定义D都应由相同的标记序列组成
......

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

在您的情况下,由于宏技巧,您有两个类定义Action及其内联成员函数Action::init和,它们由不同的标记序列组成。Action::execute


推荐阅读