编译时符号被#定义,但#ifdef看不到它

A compile-time symbol was #defined but #ifdef does not see it

本文关键字:#ifdef 看不到 定义 符号 编译      更新时间:2023-10-16

我有一个测试类在头文件中声明,并在单独的文件中定义。这个类在Windows下必须以不同的方式编译,所以我使用#if defined ( _WINDOWS_ )。当我编译同样包含#if defined ( _WINDOWS_ )的cpp文件时,尽管符号_WINDOWS_是在另一个文件中定义的,但编译该文件时,就好像它没有定义一样。当我编译代码时,我得到以下错误:

错误代码:错误lnk2019未解析的外部符号公共

源代码

// test.h
class Test
{
public:
#if defined (_WINDOWS_)
void printwindow();
#endif
void notwindows();
}; 
//test.cpp
#include "test.h"
 #if defined (_WINDOWS_)
void Test::printwindow()
{
cout << "i am windows ";
}
 #endif

void test::notwindows()
{
cout << " not windows " ;
}

//main.cpp
#include "windows.h"
#include "test.h"
void main()
{
test t1 ; 
t1.printwindow()  // OK I have declared function so my _WINDOWS_ is available but when i run it i get
}

错误代码:错误lnk2019未解析的外部符号公共

注意:如果我直接定义函数,它可以正常工作,没有任何问题

// test.h
    class Test
    {
    public:
    #if defined (_WINDOWS_)
    void printwindow(){couT << "i am window" }
    #endif
    void notwindows();
    };

但我不喜欢这种方法。我更喜欢在单独的文件(h和cpp)中定义它们。

对于条件编译测试,最好使用_WIN32而不是_WINDOWS_。仅当包含windows.h时才定义_WINDOWS_,而编译器会为Windows目标的任何构建自动定义_WIN32,而不管包含什么标头。在您的情况下,_WINDOWS_是在编译main.cpp时定义的,但在编译test.cpp时没有定义,因为test.cpp不包括windows.h

此外,_WINDOWS_宏定义是windows.h报头的实现细节,并且不保证被使用。例如,windows.h的MinGW版本没有定义_WINDOWS_

您需要在test.cpp文件中包含windows.h

编译test.cpp时,它没有定义_WINDOWS_符号。因此,它创建了一个没有windows函数的对象文件。

然后在test.hpp中,它使用了这个符号,因为您在main.cpp中包含了windows.h如果您更改includes的顺序,它的行为将有所不同。您应该重新思考如何选择不依赖于includes顺序的windows版本(例如,请参阅关于_WIN32_的其他答案)。

您不能使用另一个代码文件(main.cpp)中的一些定义来更改已编译的对象文件(test.cpp)中的代码