Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 静态整数、编译单元和三元运算符_C++_Compilation_Linker_Undefined - Fatal编程技术网

C++ 静态整数、编译单元和三元运算符

C++ 静态整数、编译单元和三元运算符,c++,compilation,linker,undefined,C++,Compilation,Linker,Undefined,//SomeCls.h class SomeCls { static const int PERIOD_ALARM_NORMAL = 5; static const int PERIOD_ALARM_THRESH = 1; void method() { bool b = true; const int d = b ? PERIOD_ALARM_THRESH :

//SomeCls.h

class SomeCls
    {
    static const int PERIOD_ALARM_NORMAL    =   5;          
    static const int PERIOD_ALARM_THRESH    =   1;          

    void method()
    {
        bool b = true;
        const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
    }

    } obj;
它会建造好的。现在取出method()实现并将其放在cpp文件中:

 //SomeCls.cpp
#include "SomeCls.h"

void SomeCls::method()
    {
        bool b = true;
        const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
    }
const int SomeCls::PERIOD_ALARM_NORMAL;
const int SomeCls::PERIOD_ALARM_THRESH;
linker先生为什么这么说

未定义对
SomeCls::PERIOD\u ALARM\u NORMAL'的引用未定义
参考
SomeCls::周期\警报\阈值'

?

谢谢

编辑: 在我看来,在.h里面,三元运算符把静态常数作为右值,但是。。。在degrative.h之外,它将它们视为左值,需要定义。
这就是我从下面的答案中理解的。感谢Bada编译器(一些eabi linux之类的东西)

如果编译器看不到所有静态类常量的值,那么您必须为它们提供定义,以便它们实际存储在某个地方。将以下内容添加到您的cpp文件:

 //SomeCls.cpp
#include "SomeCls.h"

void SomeCls::method()
    {
        bool b = true;
        const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
    }
const int SomeCls::PERIOD_ALARM_NORMAL;
const int SomeCls::PERIOD_ALARM_THRESH;

如果编译器无法看到所有静态类常量的值,那么您必须为它们提供定义,以便它们实际存储在某个地方。将以下内容添加到您的cpp文件:

 //SomeCls.cpp
#include "SomeCls.h"

void SomeCls::method()
    {
        bool b = true;
        const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
    }
const int SomeCls::PERIOD_ALARM_NORMAL;
const int SomeCls::PERIOD_ALARM_THRESH;

如果出于任何原因,编译器只是拒绝链接代码(如GCC 4.4.5所做的),这里有一个简单的修复方法:用
枚举替换
静态常量int
s

// someclass.h
// include guards, blabla

class SomeClass
{
    enum AlarmPeriod{
      PERIOD_ALARM_NORMAL = 5,
      PERIOD_ALARM_THRESH = 1
    };      

public:
    void method();
};

// someclass.cpp
#include "someclass.h"

void SomeClass::method(){
    bool b = true;
    const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
}

// main.cpp
#include "someclass.h"

int main(){
  someclass sc;
  sc.method();
}
这与GCC4.4.5有着清晰的联系,GCC4.4.5与前一版本没有联系,尽管两者在技术上是相同的


请注意,除其他外,您不能再使用
PERIOD\u ALARM\u NORMAL
PERIOD\u ALARM\u TRESH
的地址,因为这两个名称只是各自值的别名。

如果编译器出于任何原因拒绝链接代码(如GCC 4.4.5),这里有一个简单的修复方法:用
enum
替换
static const int
s

// someclass.h
// include guards, blabla

class SomeClass
{
    enum AlarmPeriod{
      PERIOD_ALARM_NORMAL = 5,
      PERIOD_ALARM_THRESH = 1
    };      

public:
    void method();
};

// someclass.cpp
#include "someclass.h"

void SomeClass::method(){
    bool b = true;
    const int d = b ? PERIOD_ALARM_THRESH : PERIOD_ALARM_NORMAL;
}

// main.cpp
#include "someclass.h"

int main(){
  someclass sc;
  sc.method();
}
这与GCC4.4.5有着清晰的联系,GCC4.4.5与前一版本没有联系,尽管两者在技术上是相同的


请注意,除其他外,您不能再使用
PERIOD\u ALARM\u NORMAL
PERIOD\u ALARM\u TRESH
的地址,因为这两个名称只是各自值的别名。

这是GCC限制,但它完全是标准配置。从技术上讲,
静态常量int
仍然是一个
左值
。您提供了内联值,因此编译器几乎总是将其用作
rvalue
。有一个例外。三元运算符编译器发出的抽象指令查询
左值的地址。因此,您看到了错误

您可以使用
enum
来解决这个问题。或者,如果您使用的是新版本的GCC
constexpr
,它被添加到标准中以解决这个确切的问题(命名并键入右值)

或者,您可以为链接器提供常量的定义。例如,在类cpp文件中添加a行,如

// I wish I had constexpr
const int SomeCls::PERIOD_ALARM_NORMAL;
const int SomeCls::PERIOD_ALARM_THRESH;

作为旁注:我是类范围常量的
static const
的坚定支持者。然后我发现MSVC不允许值为inline的
静态常量float
。因此,可以移植到
静态常量中的唯一值是整数,在这种情况下,
enum
s提供了所有相同的特性,并保证它们永远不会自动转换为
左值

这是一个GCC限制,但它完全是标准配置。从技术上讲,
静态常量int
仍然是一个
左值
。您提供了内联值,因此编译器几乎总是将其用作
rvalue
。有一个例外。三元运算符编译器发出的抽象指令查询
左值的地址。因此,您看到了错误

您可以使用
enum
来解决这个问题。或者,如果您使用的是新版本的GCC
constexpr
,它被添加到标准中以解决这个确切的问题(命名并键入右值)

或者,您可以为链接器提供常量的定义。例如,在类cpp文件中添加a行,如

// I wish I had constexpr
const int SomeCls::PERIOD_ALARM_NORMAL;
const int SomeCls::PERIOD_ALARM_THRESH;

作为旁注:我是类范围常量的
static const
的坚定支持者。然后我发现MSVC不允许值为inline的
静态常量float
。因此,可以移植到
静态常量中的唯一值是整数,在这种情况下,
enum
s提供了所有相同的特性,并保证它们永远不会自动转换为
左值

,为什么链接器会这样说?你到底想把什么联系起来?@Scarlet:我想你误解了什么。OP不想测试
d==b
,他想分配
d
,在
b
上测试。请不要对变量名使用所有的大写字母。它们传统上只用于预处理器宏(除了读起来很累之外)。@Xeo I'm blind:)删除注释以避免产生误解,谢谢。FWIW,这段代码在Clang 3.1中运行得很好,但在GCC 4.4.5中却没有。你在使用哪种编译器?当你做什么时,为什么链接器会这么说?你到底想把什么联系起来?@Scarlet:我想你误解了什么。OP不想测试
d==b
,他想分配
d
,在
b
上测试。请不要对变量名使用所有的大写字母。它们传统上只用于预处理器宏(除了读起来很累之外)。@Xeo I'm blind:)删除注释以避免产生误解,谢谢。FWIW,这段代码在Clang 3.1中运行得很好,但在GCC 4.4.5中却没有。你在使用哪个编译器?+1,我不知道“如果它看不到它们的值”part@SethCarnegie:嗯,可能是另一种情况。。。“在好的情况下,您可能不需要定义,因为编译器已经知道这些值,并且可以在不需要实际变量的情况下将它们折叠到代码中”。。。