Tag: 语言律师

删除C ++ 0x中的nullptr是否安全?

在c++03中很明显,删除空指针没有效果。 事实上,在§5.3.5/2中明确指出: 在任何一种情况下,如果delete的操作数的值是空指针,则操作不起作用。 但是,在目前的草案为c++0x这个句子似乎缺less。 在草稿的其余部分,我只能find句子,说明如果delete-expression的操作数不是空指针常量会发生什么情况。 是删除仍然在c++0x定义的空指针,如果是的话,在哪里? 笔记: 有明显的间接证据表明它仍然是明确的。 首先,在§5.3.5/2有两个句子说明 在第一个替代(删除对象)中,删除操作数的值可能是空指针值,… 和 在第二种select(删除数组)中,删除操作数的值可能是空指针值或… 这些说操作数被允许为空,但它们自己并不真正定义如果是的话会发生什么。 其次,改变delete 0的含义是一个重大的突破性改变,标准委员会将不太可能做出这个特殊的改变。 此外,在c++0x草案的兼容性附件(附件C)中没有提到这是一个突破性的变化。 然而,附件C是一个信息性的部分,所以这对标准没有任何解释。 另一方面,删除空指针需要不起作用意味着额外的运行时检查。 在许多代码中,操作数不能为空,所以这个运行时检查与零开销原则相冲突。 也许委员会只是决定改变行为,使标准的c + +更符合语言设定的目标。

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

代码示例: struct name { int a, b; }; int main() { &(((struct name *)NULL)->b); } 这是否会导致未定义的行为? 我们可以辩论它是否“解除null”,然而C11并没有定义“dereference”这个术语。 6.5.3.2/4清楚地说,在空指针上使用*会导致未定义的行为; 但是它并没有对->表示同样的效果,也没有将a -> b定义为(*a).b ; 它对每个运营商都有单独的定义。 6.5.2.3/4中的->的语义说: 后缀expression式后跟 – >运算符,一个标识符指定一个结构或联合对象的成员。 该值是第一个expression式所指向的对象的指定成员的值,并且是一个左值。 但是, NULL不指向一个对象,所以第二个句子似乎没有指定。 相关的也许是6.5.3.2/1: 约束: 一元&运算符的操作数应该是函数标识符, []或一元运算符的结果,或者是一个左值,它指定一个不是位域的对象 ,并且不用寄存器存储类说明符声明。 但是我觉得粗体文本是有缺陷的,应该读取可能指定一个对象的左值,按照6.3.2.1/1( 左值的定义) – C99弄乱了左值的定义,所以C11不得不重写它,也许这个节错过​​了。 6.3.2.1/1确实说: 左值是一个expression式(具有非空的对象types),可能指定一个对象; 如果左值在评估时没有指定对象,则行为是不确定的 然而&运算符确实评估它的操作数。 (它不访问存储的值,但是不同)。 这个长长的推理链似乎暗示了代码会导致UB,但是它相当脆弱,我不清楚标准的作者所打算的。 如果实际上他们打算做什么,而不是让我们来辩论:)

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

纯虚拟函数是那些虚拟的成员函数,并具有纯指定符 ( = 0; ) C ++ 03 第10.4条第2款告诉我们什么是抽象类,作为一个附注,下面是: [注:一个函数声明不能​​同时提供一个纯粹的说明符和一个定义 – 结束注释] [例子: struct C { virtual void f() = 0 { }; // ill-formed }; – 例子] 对于那些对这个问题不太熟悉的人,请注意, 纯虚函数可以有定义,但是上面提到的条款禁止这样的定义出现在内联(lexically in-class)。 (对于定义纯虚函数的使用,您可能会看到,例如, GotW ) 现在所有其他types的function都可以提供一个一stream的定义,而这种限制似乎是乍看起来绝对是人为的和无法解释的。 想想看,似乎是这样的第二次和随后的一瞥:)但我相信如果没有一个具体的原因这个限制不会在那里。 我的问题是:有人知道这些具体原因吗? 好的猜测也是受欢迎的。 笔记: MSVC确实允许PVF具有内联定义。 所以不要感到惊讶:) 这个问题中的内联单词并不是指inline关键字。 这应该是词汇在课堂上

使用std :: bind与成员函数,使用对象指针或不是这个参数?

当使用std::bind绑定一个成员函数时,第一个参数是这个对象的this指针。 然而,它将作为指针传递给对象,而不是。 请参阅以下程序: #include <iostream> #include <functional> struct foo { void bar(int v) { std::cout << "foo::bar – " << v << '\n'; } }; int main() { foo my_foo; auto f1 = std::bind(&foo::bar, my_foo, 1); auto f2 = std::bind(&foo::bar, &my_foo, 2); f1(); f2(); } 铛和海湾合作委员会编译这没有抱怨,结果适用于两个绑定: foo :: bar – 1 foo :: bar – […]

什么是“回拨地狱”以及RX如何解决这个问题?

有人可以给一个清晰的定义,一个简单的例子,解释什么是一个“callback地狱”的人不知道JavaScript和node.js? 什么时候(在什么样的设置)发生“callback地狱问题”? 为什么会发生? “callback地狱”总是与asynchronous计算有关吗? 或者也可以在单线程应用程序中“callback地狱”? 我在Coursera参加了Reactive Course,Erik Meijer在他的一个演讲中表示,RX解决了“回拨地狱”的问题。 我问在Coursera论坛上什么是“回拨地狱”,但我没有明确的答案。 通过一个简单的例子解释“callback地狱”之后,你能否展示RX如何解决这个简单例子中的“callback地狱问题”?

空引用是可能的吗?

这段代码是否有效(和定义的行为)? int &nullReference = *(int*)0; 即使在使用-Wall , -Wextra , -std=c++98 , -pedantic , -Weffc++时,g ++和clang ++都可以毫不-Wextra编译它。 当然,这个引用实际上并不是null,因为它不能被访问(这意味着解引用一个空指针),但是我们可以通过检查它的地址来检查它是否为null: if( & nullReference == 0 ) // null reference

关于如何调用一个向量来改变容量,标准说的是什么?

本网站暗示,清除vector可能会改变容量: http://en.cppreference.com/w/cpp/container/vector/clear 在调用clear()之后,许多实现不会释放分配的内存,实际上将vector的capacity()保持不变。 但根据詹姆斯·坎泽的说法,这是错误的,标准要求明确不会改变能力。 标准说什么?

在初始化程序列表中,同一个variables的多个variables是未定义的行为

考虑下面的代码: int main() { int count = 0 ; int arrInt[2] = { count++, count++ } ; return 0 ; } 如果我们使用clang -std=c++03编译代码,则会产生以下警告( 现场示例 ): warning: multiple unsequenced modifications to 'count' [-Wunsequenced] int arrInt[2] = { count++, count++ } ; ^ ~~ 我不提倡这样的代码,但是类似的代码出现在另一个问题上,并且根据标准的C ++ 11是否定义了代码 。 在C ++ 11中,此行为是根据初始化程序列表中的多个突变未定义的行为定义的行为 ,实际上,如果使用-std=c++11则警告消失。 如果我们看一个预先的C ++ 11 草案标准,它不具有相同的语言覆盖初始化列表,所以看起来我们留下了Chapter 5 […]

非序列值计算(aka序列点)

对不起再次打开这个话题,但想到这个话题本身已经开始给我一个未定义的行为。 想要进入明确的行为区域。 特定 int i = 0; int v[10]; i = ++i; //Expr1 i = i++; //Expr2 ++ ++i; //Expr3 i = v[i++]; //Expr4 我想到了上面的expression式(按此顺序) operator=(i, operator++(i)) ; //Expr1 equivalent operator=(i, operator++(i, 0)) ; //Expr2 equivalent operator++(operator++(i)) ; //Expr3 equivalent operator=(i, operator[](operator++(i, 0)); //Expr4 equivalent 现在来到这里的行为是从C ++ 0x重要的引号。 “对expression式(或子expression式)的评估通常包括值计算(包括确定左值评估对象的身份和获取先前赋值给对象进行右值评估的值)以及副作用的启动“。 $ 1.9 / 15-“如果对标量对象的副作用不是相对于同一个标量对象的另一个副作用或使用相同标量对象的值进行值计算,那么行为是未定义的。 [注:与不同参数expression式相关的值计算和副作用是不确定的。 – […]

访问所有types的文字工作属性,但不是`int`; 为什么?

我已经读过,python中的所有东西都是一个对象,因此我开始尝试不同的types,并在其上调用__str__ – 起初我感觉非常兴奋,但后来我感到困惑。 >>> "hello world".__str__() 'hello world' >>> [].__str__() '[]' >>> 3.14.__str__() '3.14' >>> 3..__str__() '3.0' >>> 123.__str__() File "<stdin>", line 1 123.__str__() ^ SyntaxError: invalid syntax 为什么something .__str__()除了int之外还有其他所有的东西? 123不是inttypes的对象吗?