标签: language-lawyer

未评估的除以0未定义的行为?

我对以下代码中的一些同事存在分歧:

int foo ( int a, int b )
{
    return b > 0 ? a / b : a;
}
Run Code Online (Sandbox Code Playgroud)

此代码是否显示未定义的行为?

编辑:分歧开始于过度热切的优化编译器中的错误,其中b > 0检查已经过优化.

c c++ language-lawyer

61
推荐指数
3
解决办法
3815
查看次数

std :: ignore with structured bindings?

序幕:

std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();
Run Code Online (Sandbox Code Playgroud)

C++ 1z将引入结构化绑定的语法,这样可以编写代替

int a, b, c;
std::tie(a, b, c) = f();
Run Code Online (Sandbox Code Playgroud)

就像是

auto [a, b, c] = f();
Run Code Online (Sandbox Code Playgroud)

但是,std::tie也允许指定std::ignore忽略某些组件,例如:

std::tie(a, b, std::ignore, c) = g();
Run Code Online (Sandbox Code Playgroud)

是否可以使用新的结构化绑定语法执行类似的操作?它会如何工作?

c++ language-lawyer c++17

61
推荐指数
4
解决办法
8767
查看次数

类静态变量初始化顺序

我有一个A类,它有两个静态变量.我想用另一个不相关的静态变量初始化一个,就像这样:

#include <iostream>
class A
{
public:
    static int a;
    static int b;
};

int A::a = 200;
int a = 100;
int A::b = a;
int main(int argc, char* argv[])
{
    std::cout << A::b << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是200.所以,谁能告诉我为什么?

c++ scope language-lawyer

61
推荐指数
4
解决办法
2354
查看次数

我们真的需要C++ 11中的"枚举类"吗?

我们的时候,

struct E { enum E_ { HELLO }; }; // 'E' is inheritable
Run Code Online (Sandbox Code Playgroud)

那我们为什么需要,

enum class E { HELLO };  // 'E' is not inheritable
Run Code Online (Sandbox Code Playgroud)

IMO第二版不提供比第一版更多的功能.我不认为这enum class只是为了节省2个花括号{};!我错过了任何重要方面吗?

作为未成年人的问题,是有什么区别enum classenum struct其他比语法(因为两者都具有public访问说明符)?

c++ enums language-lawyer c++11

60
推荐指数
4
解决办法
3万
查看次数

`sizeof`*真的*评估为`std :: size_t`吗?它可以?

采取以下标准段落:

[C++11: 5.3.3/6]:结果sizeofsizeof...是类型的常量std::size_t.[注意: std::size_t在标准标题<cstddef>(18.2)中定义. - 尾注]

现在:

[C++11: 18.2/6]:该类型size_t是一个实现定义的无符号整数类型,其大小足以包含任何对象的字节大小.

当然,该段落并不要求这size_t是一个定义的类型别名typedef,但由于它明确声明可以通过标准标题提供<cstddef>,我认为我们可以认为如果没有包含它<cstddef>应该删除任何size_t可用的保证.一个程序.

但是,根据第一个引用,我们可以无论如何获得类型的表达式std::size_t.

我们实际上可以证明这两个事实:

int main()
{
    typedef decltype(sizeof(0)) my_size_t;

    my_size_t x   = 0;  // OK
    std::size_t y = 1;  // error: 'size_t' is not a member of 'std'
}
Run Code Online (Sandbox Code Playgroud)

std::size_t该程序不可见,但sizeof(0)仍然给我们一个?真?

因此,说它5.3.3/6有缺陷的,并且它实际上具有"与std::size_t解决的任何类型相同的类型",而不是 std::size_t它本身,这是不正确的吗?

当然,如果 …

c++ std language-lawyer c++11

60
推荐指数
4
解决办法
3173
查看次数

为什么clang的stdbool.h包含#define false false

在被编译器错误指向后,我注意到clang的stdbool.h文件包括(除其他外)以下行:

#define bool  bool
#define false false
#define true  true
Run Code Online (Sandbox Code Playgroud)

它们包含在一个间接#ifdef强制执行的块中__cplusplus,因此c ++标记即使stdbool.h是C头也是如此.

那些定义需要什么?我想他们需要一些与预处理器相关的原因,但我有兴趣知道标准的哪个部分或者哪个技术原因使得clang必须包括那些.

c++ clang language-lawyer

60
推荐指数
2
解决办法
3339
查看次数

在C++ 17中更改了受保护构造函数的规则?

我有这个测试用例:

struct A{ protected: A(){} };
struct B: A{};
struct C: A{ C(){} };
struct D: A{ D() = default; };

int main(){
    (void)B{};
    (void)C{};
    (void)D{};
}
Run Code Online (Sandbox Code Playgroud)

gcc和clang都用C++ 11和C++ 14模式编译它.两者都在C++ 17模式下失败:

$ clang++ -std=c++17 main.cpp 
main.cpp:7:10: error: base class 'A' has protected default constructor
        (void)B{};
                ^
main.cpp:1:22: note: declared protected here
struct A{ protected: A(){} };
                     ^
main.cpp:9:10: error: base class 'A' has protected default constructor
        (void)D{};
                ^
main.cpp:1:22: note: declared protected here
struct A{ protected: A(){} };
                     ^
2 …
Run Code Online (Sandbox Code Playgroud)

c++ constructor protected language-lawyer c++17

60
推荐指数
2
解决办法
3501
查看次数

为什么在C ++ 17中基于范围的“ for”循环规范发生了变化?

我查看了一些丑陋的代码(在迭代时修改了基础序列),并探索了基于范围的for循环的定义,我去了cppreference

在那里,我注意到了一些奇怪的事情:

基于范围的for循环在C ++ 17中已更改,但我看不到更改的原因,并且代码对我来说看起来相同(只是“重构”)。因此,旧的是:

{
  auto && __range = range_expression;
  for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
    range_declaration = *__begin;
    loop_statement
  }
} 
Run Code Online (Sandbox Code Playgroud)

新的是

{
  auto && __range = range_expression;
  auto __begin = begin_expr;
  auto __end = end_expr;
  for ( ; __begin != __end; ++__begin) {
    range_declaration = *__begin;
    loop_statement
  }
} 
Run Code Online (Sandbox Code Playgroud)

为什么要进行此更改,并且它会使任何合法的C ++ 14程序在C ++ 17中表现出未定义的行为(UB)?

c++ for-loop language-lawyer c++17

60
推荐指数
2
解决办法
5143
查看次数

纯虚函数可能没有内联定义.为什么?

纯虚函数是那些虚拟的成员函数,具有pure-specifier(= 0;)

C++ 03第10.4条第2款告诉我们抽象类是什么,作为旁注,以下内容:

[注意:函数声明不能​​同时提供纯指定符和定义-end note] [示例:

struct C {
virtual void f() = 0 { }; // ill-formed
};
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

对于那些不太熟悉这个问题的人,请注意纯虚函数可以有定义,但上面提到的条款禁止这些定义以内联方式出现(lexically in-class).(对于定义纯虚函数的用法,您可能会看到,例如,这个GotW)

现在,对于所有其他类型和类型的函数,它被允许提供类内定义,并且这种限制乍一看似乎绝对是人为的和莫名其妙的.想到这一点,它似乎在第二次和随后的一瞥:)但我相信如果没有具体原因那么限制将不存在.

我的问题是:有人知道这些具体原因吗?也欢迎良好的猜测.

笔记:

  • MSVC确实允许PVF具有内联定义.所以不要惊讶:)
  • inline此问题中的单词未引用内联关键字.它应该是词汇上的词汇

c++ pure-virtual language-lawyer

59
推荐指数
3
解决办法
5342
查看次数

在C++ 11 lambda中通过引用捕获引用

考虑一下:

#include <functional>
#include <iostream>

std::function<void()> make_function(int& x) {
    return [&]{ std::cout << x << std::endl; };
}

int main() {
    int i = 3;
    auto f = make_function(i);
    i = 5;
    f();
}
Run Code Online (Sandbox Code Playgroud)

是否保证在5不调用未定义行为的情况下输出该程序?

我理解如果我x通过value([=])捕获它是如何工作的,但我不确定我是否通过引用捕获它来调用未定义的行为.可能是我在make_function返回后最终会有一个悬空引用,或者只要原始引用的对象仍然存在,捕获的引用是否可以保证工作?

在这里寻找明确的基于标准的答案:) 到目前为止它在实践中运作良好;)

c++ lambda language-lawyer c++11

59
推荐指数
2
解决办法
2万
查看次数

标签 统计

c++ ×10

language-lawyer ×10

c++11 ×3

c++17 ×3

c ×1

clang ×1

constructor ×1

enums ×1

for-loop ×1

lambda ×1

protected ×1

pure-virtual ×1

scope ×1

std ×1