constexpr未定义的行为 [英] constexpr undefined behaviour

查看:297
本文介绍了constexpr未定义的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试 constexpr 。在我的测试编译器(g ++ 4.6),这不能编译带有超出访问的错误。是否需要编译器 在编译时发现这一点?

I've been experimenting with constexpr. On my test compiler (g++ 4.6) this fails to compile with an error about out of bounds access. Is a compiler required to spot this at compile time?

#include <iostream>

constexpr const char *str = "hi";

constexpr int fail() {
  return str[1000]; // Way past the end!
}

template <int N>
struct foo {
  static void print() { std::cout << N << std::endl; }
};

int main() {  
  foo<fail()>::print();
}


推荐答案

§5.19/ 2第二页;它真的应该分成许多段)禁止包含

§5.19/2 (on the second page; it really should be split into many paragraphs) forbids constant expressions containing


- 一个左值到值的转换除非应用于

— an lvalue-to-rvalue conversion (4.1) unless it is applied to



- 指向非易失性const的整数或枚举类型的glvalue对象与前面的初始化,用常量表达式初始化,或

— a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression, or

- 一个字面类型的glvalue,指的是用constexpr定义的非易失性对象,此类对象的子对象

— a glvalue of literal type that refers to a non-volatile object defined with constexpr, or that refers to a sub-object of such an object



str [1000] 转换为 *(str + 1000),不指向 str ,与in-bounds数组访问相反。因此,这是一个可诊断的规则,编译器需要投诉。

str[1000] translates to * ( str + 1000 ), which does not refer to a subobject of str, in contrast with an in-bounds array access. So this is a diagnosable rule, and the compiler is required to complain.

EDIT:似乎有一些混淆, 。当它需要是常量时,编译器检查表达式是否符合§5.19。如果表达式不满足要求,编译器需要抱怨。实际上,需要对任何可能导致未定义行为的任​​何事情验证常量表达式。*这可能涉及或可能不涉及尝试对表达式求值。

It seems there's some confusion about how this diagnosis comes about. The compiler checks an expression against §5.19 when it needs to be constant. If the expression doesn't satisfy the requirements, the compiler is required to complain. In effect, it is required to validate constant expressions against anything that might otherwise cause undefined behavior.* This may or may not involve attempting to evaluate the expression.

*在C ++ 11,不是数学定义的结果。在C ++ 14中,一个具有未定义行为的操作,根据定义(§1.3.24)忽略了实现可能定义为回退的行为。

 * In C++11, "a result that is not mathematically defined." In C++14, "an operation that would have undefined behavior," which by definition (§1.3.24) ignores behavior that the implementation might define as a fallback.

这篇关于constexpr未定义的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆