标签: language-lawyer

新char实际上是否保证类类型的对齐内存?

通过new char[sizeof(T)]保证分配一个缓冲区来分配一个缓冲区,该内存是为该类型正确对齐的T,其中所有成员T都有其自然的,实现定义的对齐方式(也就是说,您没有使用该alignas关键字来修改它们的对齐方式).

我已经看到这个保证在这里得到了一些答案,但我并不完全清楚标准是如何达到这个保证的.5.3.4-10标准给出了基本要求:基本上new char[]必须与之对齐max_align_t.

我所缺少的是所说的位alignof(T)总是有效的对齐,最大值为max_align_t.我的意思是,这似乎是显而易见的,但结构的最终对齐必须至多max_align_t吗?即使点3.11-3表示可能支持扩展对齐,编译器可能自己决定一个类是一个过度对齐的类型?

c++ language-lawyer c++11

57
推荐指数
2
解决办法
2519
查看次数

int8_t和uint8_t是char类型吗?

鉴于这个C++ 11程序,我应该期待看到一个数字还是一个字母?还是没有期望?

#include <cstdint>
#include <iostream>

int main()
{
    int8_t i = 65;
    std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)

标准是否指定此类型是否可以是字符类型?

c++ iostream standard-library language-lawyer c++11

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

在修改后的异常上使用`throw;`

我有一个foo可以抛出bar异常的函数.

在我调用的另一个函数中,foo但是bar如果抛出,我可以向异常添加更多细节.(foo由于该函数的通用特性,我宁愿不将这些信息作为参数传递给它,因为它并不真正属于那里.)

所以我在调用者中这样做:

try {
    foo();
} catch (bar& ex){
    ex.addSomeMoreInformation(...);
    throw;
}
Run Code Online (Sandbox Code Playgroud)

throw重新抛出修改过的异常还是我需要使用throw ex;?后者可能会采用有价值的副本,所以我宁愿不这样做.还会throw带一个价值副本吗?我怀疑它不会.

(我知道我可以验证,但我担心绊倒一个未指定或未定义的构造,所以想知道肯定).

c++ exception-handling exception throw language-lawyer

57
推荐指数
2
解决办法
2765
查看次数

&((struct name*)NULL - > b)是否会在C11中导致未定义的行为?

代码示例:

struct name
{
    int a, b;
};

int main()
{
    &(((struct name *)NULL)->b);
}
Run Code Online (Sandbox Code Playgroud)

这是否会导致未定义的行为?我们可以辩论它是否"取消引用无效",但是C11没有定义术语"解除引用".

6.5.3.2/4明确指出*在空指针上使用会导致未定义的行为; 但它并没有说同样的->,也没有定义a -> b(*a).b; 它为每个运营商分别定义.

->6.5.2.3/4中的语义说:

后缀表达式后跟 - >运算符和标识符指定结构或联合对象的成员.该值是第一个表达式指向的对象的指定成员的值,并且是左值.

但是,NULL并没有指向一个对象,所以第二句似乎没有说明.

相关的可能是6.5.3.2/1:

约束:

一元运算&符的操作数应该是函数指示符,[]一元或一元运算*符的结果 ,或者是一个左值,它指定一个不是位字段的对象,并且不用寄存器存储类说明符声明.

但是我觉得粗体文本是有缺陷的并且应该读取可能指定对象的左值,按照6.3.2.1/1(左值的定义) - C99弄乱了左值的定义,所以C11必须重写它,也许这个部分错过了.

6.3.2.1/1确实说:

左值是一个表达式(对象类型不是void)可能指定一个对象; 如果左值在评估时未指定对象,则行为未定义

&操作员确实评估了它的操作数.(它不访问存储的值,但这是不同的).

这种长期推理似乎表明代码会导致UB,但它相当脆弱,我不清楚标准的作者是什么意图.如果事实上他们打算做任何事情,而不是让我们讨论:)

c offsetof language-lawyer c11

57
推荐指数
4
解决办法
3483
查看次数

为什么`int;`在C中编译好,但在C++中没编译?

请考虑以下程序(请参阅此处的实时演示).

#include <stdio.h>
int main(void)
{
      int ;  // Missing variable name
      puts("Surprise");
}
Run Code Online (Sandbox Code Playgroud)

我的编译器gcc 4.8.1给出了以下警告:

[警告]空声明中无用的类型名称[默认启用]

为什么编译好?我不应该得到编译错误吗?当我将它编译为C++程序时,g ++ 4.8.1给出以下错误:

[错误]声明没有声明任何内容[-fpermissive]

c c++ gcc variable-declaration language-lawyer

57
推荐指数
3
解决办法
4532
查看次数

使用"auto"的声明是否匹配使用具体类型说明符的extern声明?

考虑以下程序:

extern int x;
auto x = 42;
int main() { }
Run Code Online (Sandbox Code Playgroud)

Clang 3.5接受它(现场演示),GCC 4.9和VS2013不接受(前者的现场演示).谁是对的,C++标准中指定的正确行为在哪里?

c++ extern language-lawyer auto

56
推荐指数
1
解决办法
1816
查看次数

[a [0]] = 1会产生未定义的行为吗?

这个C99代码是否会产生未定义的行为?

#include <stdio.h>

int main() {
  int a[3] = {0, 0, 0};
  a[a[0]] = 1;
  printf("a[0] = %d\n", a[0]);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在声明中a[a[0]] = 1;,a[0]都是读取和修改.

我看了ISO/IEC 9899的n1124草案.它说(在6.5表达式中):

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,先前的值应该只读以确定要存储的值.

它没有提到读取对象来确定要修改的对象本身.因此,此语句可能会产生未定义的行为.

但是,我觉得很奇怪.这实际上是否会产生未定义的行为?

(我也想知道其他ISO C版本中的这个问题.)

c c99 undefined-behavior language-lawyer

56
推荐指数
4
解决办法
2611
查看次数

是否定义了std :: is_unsigned <bool> :: value?

我想知道是否

std::is_unsigned<bool>::value
Run Code Online (Sandbox Code Playgroud)

根据标准是否明确定义?

我问这个问题因为typename std::make_unsigned<bool>::type没有明确定义.

c++ unsigned boolean language-lawyer c++14

56
推荐指数
4
解决办法
2716
查看次数

函数返回值是自动对象,因此可以保证被破坏吗?

在[except.ctor]中,标准(N4140)保证:

...自从输入try块以来构造的所有自动对象都会调用析构函数...

但是在下面的例子中,空输出证明函数的返回值foo没有被破坏,尽管它已被构造.使用g ++(5.2.1)和clang ++(3.6.2-1)以及选项编译-O0 -fno-elide-constructors -std=c++14.

struct A { ~A() { cout << "~A\n"; } };

struct B { ~B() noexcept(false) { throw 0; } };

A foo() {
  B b;
  return {};
}

int main() {
  try { foo(); }
  catch (...) { }
}
Run Code Online (Sandbox Code Playgroud)

这是g ++和clang ++中的错误,还是函数返回值不被视为自动对象,还是C++语言中的循环漏洞?

在[stmt.return],[expr.call]或[dcl.fct]中都没有找到一个明确的语句,函数返回值是否被视为自动对象.我找到的最接近的提示是6.3.3 p2:

......退货声明可能涉及临时物体的构造和复制或移动......

和5.2.2 p10:

如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对象类型的右值引用,则为xvalue,否则为prvalue.

c++ exception-handling return return-value language-lawyer

56
推荐指数
3
解决办法
1927
查看次数

是++ ++ ptr ++在c ++中的未定义行为?

我在测试中被问到以下问题(我不想自己编写.测试问它.我知道它的代码还不错)关于评估++*ptr ++

int Ar[ ] = { 6 , 3 , 8 , 10 , 4 , 6 , 7} ;
int *Ptr = Ar  ;
cout<<++*Ptr++  ;
Run Code Online (Sandbox Code Playgroud)

但是,我怀疑这是未定义的行为,因为它可以是(++*ptr)++或两者++(*ptr++).是吗?我不太熟悉文档,所以我找不到任何东西.

c++ language-lawyer

56
推荐指数
2
解决办法
3318
查看次数