通过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++ 11程序,我应该期待看到一个数字还是一个字母?还是没有期望?
#include <cstdint>
#include <iostream>
int main()
{
int8_t i = 65;
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
标准是否指定此类型是否可以是字符类型?
我有一个foo可以抛出bar异常的函数.
在我调用的另一个函数中,foo但是bar如果抛出,我可以向异常添加更多细节.(foo由于该函数的通用特性,我宁愿不将这些信息作为参数传递给它,因为它并不真正属于那里.)
所以我在调用者中这样做:
try {
foo();
} catch (bar& ex){
ex.addSomeMoreInformation(...);
throw;
}
Run Code Online (Sandbox Code Playgroud)
会throw重新抛出修改过的异常还是我需要使用throw ex;?后者可能会采用有价值的副本,所以我宁愿不这样做.还会throw带一个价值副本吗?我怀疑它不会.
(我知道我可以验证,但我担心绊倒一个未指定或未定义的构造,所以想知道肯定).
代码示例:
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,但它相当脆弱,我不清楚标准的作者是什么意图.如果事实上他们打算做任何事情,而不是让我们讨论:)
请考虑以下程序(请参阅此处的实时演示).
#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]
考虑以下程序:
extern int x;
auto x = 42;
int main() { }
Run Code Online (Sandbox Code Playgroud)
Clang 3.5接受它(现场演示),GCC 4.9和VS2013不接受(前者的现场演示).谁是对的,C++标准中指定的正确行为在哪里?
这个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版本中的这个问题.)
我想知道是否
std::is_unsigned<bool>::value
Run Code Online (Sandbox Code Playgroud)
根据标准是否明确定义?
我问这个问题因为typename std::make_unsigned<bool>::type没有明确定义.
在[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.
我在测试中被问到以下问题(我不想自己编写.测试问它.我知道它的代码还不错)关于评估++*ptr ++
int Ar[ ] = { 6 , 3 , 8 , 10 , 4 , 6 , 7} ;
int *Ptr = Ar ;
cout<<++*Ptr++ ;
Run Code Online (Sandbox Code Playgroud)
但是,我怀疑这是未定义的行为,因为它可以是(++*ptr)++或两者++(*ptr++).是吗?我不太熟悉文档,所以我找不到任何东西.