为什么C ++ std :: min在O0上编译时不能使用静态字段作为其参数?

问题描述

相同的代码,用O0编译,它将报告错误:

//============================================================================
// Name        : test.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++,Ansi-style
//============================================================================

#include <iostream>
#include <stdint.h>
using namespace std;
class foo{

      static const int64_t MAX_THREAD_NUM = 10 * 1000;


public:
      void test();
};

void foo::test(){
    int64_t a = 100;
//  int64_t tmp = MAX_THREAD_NUM;
//  int64_t min = std::min(tmp,a);


    int64_t min = std::min(MAX_THREAD_NUM,a);
    cout << min << endl; // prints !!!Hello World!!!

}

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    return 0;
}

g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/test.d" -MT"src/test.o" -o "src/test.o" "../src/test.cpp"

g++  -o "test"  ./src/test.o   
./src/test.o: In function `foo::test()':
/home/foo/eclipse-workspace/test/Debug/../src/test.cpp:27: undefined reference to `foo::MAX_THREAD_NUM'
collect2: error: ld returned 1 exit status
/home/foo/eclipse-workspace/test/Debug/../src/test.cpp:27: undefined reference to `foo::MAX_THREAD_NUM'

但是带有O2标志,它可以编译成功。

g++ -O2 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/test.d" -MT"src/test.o" -o "src/test.o" "../src/test.cpp"
g++  -o "test"  ./src/test.o

g ++版本: g ++(Ubuntu 4.8.5-4ubuntu8)4.8.5 版权所有(C)2015 Free Software Foundation,Inc. 这是免费软件;请参阅复制条件的来源。没有 保证;甚至不是针对特定目的的适销性或适用性

解决方法

由于您不提供ODR使用符号的定义而违反了一个定义规则(ODR),因此程序的格式不正确,不需要诊断(NDR)。{p {1}引用其参数)。

优化器会删除未使用的代码,并让您认为它是正确的。

,

@dfri指出,编译器会内联MAX_THREAD_NUM。如果我们将其更改为inline static const int64_t MAX_THREAD_NUM = 10 * 1000;,它将在O0上正常编译。否则,在类之外声明但定义变量,或将其标记为constexpr而不是const。如果在需要非const积分的地方使用静态const积分成员,则需要定义。

class foo {
      static const int64_t MAX_THREAD_NUM;
      ...
};
const int64_t foo::MAX_THREAD_NUM = 10 * 1000;

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...