c – 关于持续初始化的困惑

前端之家收集整理的这篇文章主要介绍了c – 关于持续初始化的困惑前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
cppref中,它给出了常量初始化的语法:
static T & ref = constexpr; 
static T object = constexpr;

这是我的两个问题:

Q1

低价参考T&没有const绑定到constexptr,它是常量且不可修改的?

我试着提供一些例子,但失败了:

static int& ref = 6; //error,need a `const`
 constexpr int a = 6; static int& ref = a; //error,need a `const`

Q2

常量初始化的对象是const / static是必要的吗?在the standard它说:

Constant initialization is performed if a variable or temporary object with static or thread storage duration is initialized by a constant initializer for the entity.

这里标准没有将obj指定为const-qualified / static-qualified.

解决方法

混淆是由于命名:常量初始化 [basic.start.static]/2中的术语常量和常量表达式 [expr.const]意味着在编译时可以在没有编译器的英雄努力(1)的情况下进行评估.这与常量对象的概念不同,这意味着一旦定义,对象的值就不会改变.

为了说明编译时评估的限制,让我们看看这段代码的汇编:

//case 0
int i0 = 5;
int j0 = i0;//no compil-time initialized
//case 1
const int i1=5; 
int j1=i1; //compil-time initialized
//case 2
extern const int i2=5; 
int j2=i2; //compile-time initialized
//case 3
extern const int i3; 
int j3=i3; //no compil-time initialization
//case 4
extern const int i4; 
int j4=i4; //no compil-time initialization
const int i4=5;

由gcc 7.3生成的程序集:

_GLOBAL__sub_I_example.cpp: # @_GLOBAL__sub_I_example.cpp
  mov eax,dword ptr [rip + i0]
  mov dword ptr [rip + j0],eax
  mov eax,dword ptr [rip + i3]
  mov dword ptr [rip + j3],eax
  mov dword ptr [rip + j4],5
  ret

发生了什么:

> case 0,j0未在compil-time初始化,因为i0不是constant.[expr.constant]/2.7
>情况1和2,是编译时初始化的,因为它们适合于先前规则[expr.constant]/2.7.3的例外.
> case 3和case4,j3和j4在compil-time时没有初始化,因为它们不适合这个最后的规则异常,因为它们没有先前的初始化,(至少它可以在链接解决,但这将是一个英雄的努力或依赖于实施质量)

(1)原则是语言不能太复杂,无法编译.我只是回收了模板论证演绎标准的措辞,其中术语英雄的努力似乎很明显.应用相同的原则来定义什么是常量表达式.

原文链接:https://www.f2er.com/c/119661.html

猜你在找的C&C++相关文章