给出以下函数调用:
f(g(), h())
Run Code Online (Sandbox Code Playgroud)
因为函数参数的计算顺序是不确定的(仍然是在C++ 11,据我所知的情况下),可以实现理论上执行g()和h()并行?
这种并行化只能起作用g并且h已知是相当微不足道的(在最明显的情况下,仅访问其本体的本地数据)以便不引入并发性问题但是,除了该限制之外,我看不到任何禁止它的内容.
那么,标准是否允许它?即使只是按照as-if规则?
(在这个答案中,Mankarse声称不然;但是,他没有引用标准,而我的通读[expr.call]并没有透露任何明显的措辞.)
可以在头文件中写入以下内容:
inline void f () { std::function<void ()> func = [] {}; }
Run Code Online (Sandbox Code Playgroud)
要么
class C { std::function<void ()> func = [] {}; C () {} };
Run Code Online (Sandbox Code Playgroud)
我想在每个源文件中,lambda的类型可能不同,因此包含的类型std::function(target_type的结果会有所不同).
这是一个ODR(一个定义规则)违规,尽管看起来像一个共同的模式和合理的事情?第二个示例是每次都违反ODR还是仅在头文件中至少有一个构造函数?
我知道Python中不需要分号,但它们可以用于将多个语句塞入一行,例如
>>> x = 42; y = 54
Run Code Online (Sandbox Code Playgroud)
我一直认为分号相当于换行符.所以我有点惊讶(在推特上没有Ned Batchelder)双分号是一个SyntaxError:
>>> x = 42
>>> x = 42;
>>> x = 42;;
File "<stdin>", line 1
x = 42;;
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
我假设最后一个程序相当于x = 42\n\n.我以为分号之间的陈述被视为一个空行,一个无操作.显然不是.
为什么这是一个错误?
来自http://en.cppreference.com/w/cpp/string/byte/memcpy:
如果对象不是TriviallyCopyable(例如标量,数组,C兼容结构),则行为未定义.
在我的工作中,我们使用std::memcpy了很长时间来按比例交换不是TriviallyCopyable的对象:
void swapMemory(Entity* ePtr1, Entity* ePtr2)
{
static const int size = sizeof(Entity);
char swapBuffer[size];
memcpy(swapBuffer, ePtr1, size);
memcpy(ePtr1, ePtr2, size);
memcpy(ePtr2, swapBuffer, size);
}
Run Code Online (Sandbox Code Playgroud)
从来没有任何问题.
我理解滥用std::memcpy非TriviallyCopyable对象并导致下游的未定义行为是微不足道的.但是,我的问题是:
std::memcpy当与非TriviallyCopyable对象一起使用时,为什么它本身的行为是未定义的?为什么标准认为有必要指定?
UPDATE
http://en.cppreference.com/w/cpp/string/byte/memcpy的内容已经过修改,以回应这篇文章和帖子的答案.目前的描述说:
如果对象不是TriviallyCopyable(例如标量,数组,C兼容结构),则行为是未定义的,除非程序不依赖于目标对象(不运行
memcpy)的析构函数的效果和生命周期目标对象(已结束,但未开始memcpy)由其他一些方法启动,例如placement-new.
PS
@Cubbi的评论:
@RSahu如果有东西保证UB下游,它会使整个程序不确定.但我同意在这种情况下似乎可以绕过UB并相应地修改cppreference.
每个程序员都应该知道:
在某些情况下,为了优化程序,编译器可能会修改(!p && !q)为(!(p || q)).
这两个表达式是等价的,并且评估第一个或第二个没有区别.
但是在C++中,可能会重载运算符,而重载的运算符可能并不总是尊重这个属性.因此,以这种方式转换代码实际上将修改代码.
如果编译器使用德摩根定律时!,||和&&超载?
c++ operator-overloading compiler-optimization language-lawyer
我正和我的老板争论这件事.他们说"是的,他们可以是不同的."
有可能是sizeof(T*) != sizeof(const T*)一种类型T?
这似乎是一个愚蠢的问题,但是return xxx;在一个明确定义的函数中"执行" 的确切时刻?
请参阅以下示例以了解我的意思(现在直播):
#include <iostream>
#include <string>
#include <utility>
//changes the value of the underlying buffer
//when destructed
class Writer{
public:
std::string &s;
Writer(std::string &s_):s(s_){}
~Writer(){
s+="B";
}
};
std::string make_string_ok(){
std::string res("A");
Writer w(res);
return res;
}
int main() {
std::cout<<make_string_ok()<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我天真地期待发生的事情make_string_ok被称为:
res被调用(价值res就是"A")w调用构造函数return res被执行.应该返回res的当前值(通过复制当前值res),即"A".w被称为析构函数,值res变为"AB".res函数被称为.所以我希望"A"结果,但"AB" …
考虑以下使用的简单代码new(我知道没有delete[],但它与此问题无关):
int main()
{
int* mem = new int[100];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是否允许编译器优化new呼叫?
在我的研究中,g ++(5.2.0)和Visual Studio 2015不会优化new呼叫,而clang(3.0+)则可以.所有测试都是在启用完全优化的情况下进行的(-O3用于g ++和clang,用于Visual Studio的发布模式).
是不是new在引擎盖下进行系统调用,使编译器无法(并且非法)优化它?
编辑:我现在已经从程序中排除了未定义的行为:
#include <new>
int main()
{
int* mem = new (std::nothrow) int[100];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑2:
#include <new>
int main()
{
int* mem = new (std::nothrow) int[1000];
if (mem != 0)
return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这编译没有任何警告.
这在C和C++中是合法的还是只在gcc和clang中工作?
如果它是合法的,那么在C99之后它是新东西吗?
void f(){
}
void f2(){
return f();
}
Run Code Online (Sandbox Code Playgroud)
更新
正如"Rad Lexus"建议我试过这个:
$ gcc -Wall -Wpedantic -c x.c
x.c: In function ‘f2’:
x.c:7:9: warning: ISO C forbids ‘return’ with expression, in function returning void [-Wpedantic]
return f();
Run Code Online (Sandbox Code Playgroud)
$ clang -Wall -Wpedantic -c x.c
x.c:7:2: warning: void function 'f2' should not return void expression [-Wpedantic]
return f();
^ ~~~~~
1 warning generated.
Run Code Online (Sandbox Code Playgroud)
$ gcc -Wall -Wpedantic -c x.cc
(no errors)
Run Code Online (Sandbox Code Playgroud)
$ clang -Wall -Wpedantic -c x.cc
(no errors)
Run Code Online (Sandbox Code Playgroud)
更新 …
int i = i;
int main() {
int a = a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
int a = a肯定有未定义的行为 (UB),关于它的更多细节在
读取未初始化的值总是未定义的行为吗?或者有例外吗?.
但是呢int i = i?在 C++ 中,我们可以为全局变量分配非常量值。i在遇到声明之前声明并零初始化(因为它具有文件范围)。在这种情况下,我们将0在定义的后面分配给它。可以说这没有 UB 吗?
language-lawyer ×10
c++ ×9
c++11 ×2
clang ×2
gcc ×2
c ×1
c++17 ×1
copy-elision ×1
lambda ×1
memcpy ×1
optimization ×1
python ×1
syntax-error ×1