为未来的“未设置”变量定义外部变量是一种好习惯吗?

时间:2013-05-07 14:56:46

标签: c++ extern

我正在查看一些代码示例。在.h文件中,有这个声明:

  

extern int NODATA;

在许多其他文件中用于没有逻辑值的变量。

是否有必要在其他地方定义它,还是可以将其保留为未定义?

2 个答案:

答案 0 :(得分:0)

如何使用?如果按值使用,则必须定义它 在某个地方,它将承担它给予的价值 初始化程序 - 默认情况下为0.(当然,它应该是 const。)如果它只被地址使用(即&NODATA),那么它 仍需要在某处定义。但在那种情况下, 惯用约定是使用空指针:NULL(或0, 或者如果你有C ++ 11,nullptr),没有理由这样做 否则,您也不必定义任何其他内容。

答案 1 :(得分:0)

可能技术上允许它不能在任何地方定义,这取决于你所使用的“使用”的含义,但我当然不会称之为好习惯。举例来说,以下(hackish)程序。请注意,它使用了新的C ++ 11功能,但NODATA的一些用法也适用于c ++ 03。

#include <iostream>
using std::cout;
using std::endl;

extern int NODATA;

auto size = sizeof(NODATA);
auto align = alignof(NODATA);

void f(int c = NODATA)
{
    cout << "c=" << c << endl;
}

decltype(NODATA) main()
{
    cout << "size=" << size << endl;
    cout << "align=" << align << endl;

    f(0);

    // above here should all work, below may not depending on 
    // implementation and its optimization settings

    if(false && NODATA)
    {
        cout << "false && NODATA" << endl;
    }
    else if(true || NODATA)
    {
        cout << "true || NODATA" << endl;
    }
    else
    {
        int i = NODATA;
    }

    // this would definitely cause a linker error
    // f();
    // but this may not
    false ? f() : f(1);

    f((NODATA-NODATA) + 2);
    f((NODATA/NODATA) + 2);
    f((4*NODATA)/NODATA);

    int arry[3] = { [0] = 1, [1] = NODATA, [1] = 2 };

    struct {
        int first;
        int second;
        int third;
    } strct = {.first = 1, .second = NODATA, .second = 2};

    return NODATA^NODATA;

    int i = NODATA;
}

尽管NODATA未在任何地方定义(参见http://ideone.com/hyjOxR示例运行),但其中一些结构仍然可行,但我很难想出实际使用它们的任何理由。

然而,基于您的描述,听起来其他文件正在使用NODATA来初始化和/或测试其他变量(可能不会全部优化出来):

#include "NODATA.h"

int aVariableThatIsActuallyUsed = NODATA;

void SomeInitFunc(void)
{
    aVariableThatIsActuallyUsed = 42;
}

int SomeOtherFunc(void)
{
    if(NODATA == aVariableThatIsActuallyUsed)
    {
        throw SomeException();
    }

    aVariableThatIsActuallyUsed--;

    return aVariableThatIsActuallyUsed;
}

如果是这样,则必须定义NODATA,无论是在C ++源文件,汇编文件,库还是其他地方。你知道程序编译并运行没有错误吗?