我有以下代码
int m[4]={1,2,3,4}, *y;
y=m;
*y = f(y++); // Expression A
Run Code Online (Sandbox Code Playgroud)
我的朋友告诉我,Expression A行为定义明确,但我不确定他是否正确.
根据他的功能f()介绍sequence point介于两者之间,因而行为定义明确.
有人请澄清一下.
PS:我知道我们不应该为实际目的编写这样的代码.这只是为了学习的目的.:)
void main(void)
{
int x,y,z;
x=y=z=1;
z = x && y && ++z;//is this fine?
}
Run Code Online (Sandbox Code Playgroud)
我最近开始阅读关于序列点的东西,但我无法弄清楚上面的代码示例是否正常.我知道&&运算符引入了一个序列点,所以我不太确定表达式z = x && y && ++ z的行为.有人请告诉我正确的答案.
假设我们有以下代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void guarantee(bool cond, const char *msg) {
if (!cond) {
fprintf(stderr, "%s", msg);
exit(1);
}
}
bool do_shutdown = false; // Not volatile!
pthread_cond_t shutdown_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t shutdown_cond_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Called in Thread 1. Intended behavior is to block until
trigger_shutdown() is called. */
void wait_for_shutdown_signal() {
int res;
res = pthread_mutex_lock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not lock shutdown cond mutex");
while (!do_shutdown) { // while loop guards against spurious wakeups …Run Code Online (Sandbox Code Playgroud) 现在新的c ++ 11标准已经改变了序列点的描述方式,我试图找出c ++ 03和c ++ 11之间的确切变化.
特别是,在任何情况下,看起来相同的代码在c ++ 11中都会有一个序列点而不是c ++ 03吗?
我知道写点东西
++a = a++;
Run Code Online (Sandbox Code Playgroud)
不仅是不可读的,而且还违反了c/c ++序列点.
这些限制来自哪里?在将它们视为错误之前,如何才能看到这些"问题"?
我天真地想在Perl 6和Perl 5之间进行相当多的字面上的翻译,实际上却没有,因为后增量变量的处理方式不同。
Perl 6产生了理想的结果,即幻方:[[8,1,6],[3,5,7],[4,9,2]]
my @sq; my $n = 3; my $i = 1; my $x = $n/2; my $y = 0;
@sq[($i%$n ?? $y-- !! $y++) % $n][($i%$n ?? $x++ !! $x) % $n] = $i++ for 0..$n**2 - 1;
say join ' ', $_ for @sq;
Run Code Online (Sandbox Code Playgroud)
Perl 5中的“相同”代码不:[[8,1,3],[9,5,7],[4,6,2]]
$n = 3; $i = 1; $x = $n/2; $y = 0;
$sq[($i%$n ? $y-- : $y++) % $n][($i%$n ? $x++ : $x) % $n] = $i++ for 0..$n**2 …Run Code Online (Sandbox Code Playgroud) 最近,我已经看到很多关于输出的问题,一些疯狂但语法上允许的代码语句就像是i = ++i + 1和i=(i,i++,i)+1;.实际上坦率地说,几乎没有人在实际编程中编写任何这样的代码.坦率地说,我从未在我的专业经验中遇到任何这样的代码.所以我通常最终会在SO上跳过这些问题.但是最近这种问题的绝对数量让我想到如果我错过了一些重要的理论,就是跳过这样的问题.我认为这样的Q围绕着Sequence points.我几乎不知道序列点是坦率的,我只是想知道如果不知道它在某种程度上是一个障碍.那么有人可以解释一下理论/概念Sequence points,或者如果可能的话,指向解释该概念的资源.此外,是否值得花时间了解这个概念/理论?
我怀疑根据C++标准(假设C++ 0x),以下链接函数会导致未指定的序列.只是想要一个确认,如果有人可以提供解释,我会很感激.
#include <iostream>
struct TFoo
{
TFoo(int)
{
std::cout<<"TFoo"<<std::endl;
};
TFoo foobar1(int)
{
std::cout<<"foobar1"<<std::endl;
return *this;
};
TFoo foobar2(int)
{
std::cout<<"foobar2"<<std::endl;
return *this;
};
static int bar1()
{
std::cout<<"bar1"<<std::endl;
return 0;
};
static int bar2()
{
std::cout<<"bar2"<<std::endl;
return 0;
};
static int bar3()
{
std::cout<<"bar3"<<std::endl;
return 0;
}
};
int main(int argc, char *argv[])
{
// is the sequence well defined for bar1, bar2 and bar3?
TFoo(TFoo::bar1()).foobar1(TFoo::bar2()).foobar2(TFoo::bar3());
}
Run Code Online (Sandbox Code Playgroud)
*编辑:删除函数的__fastcall说明符(不需要/与问题相关).
我以为我理解序列点在C++中是如何工作的,但是这个GeeksQuiz问题困惑了我:
int f(int &x, int c) {
c = c - 1;
if (c == 0) return 1;
x = x + 1;
return f(x, c) * x;
}
int main() {
int p = 5;
cout << f(p, p) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个问题的"正确"答案是它打印6561.事实上,在VS2013中确实如此.但是不管它是UB,因为没有保证会首先评估:f(x, c)或者x.如果f(x, c)首先被评估,我们得到6561 :整个事情变成五个递归调用:前四个(c = 5, 4, 3, 2)继续,最后一个(c = 1)终止并返回1,这9 ** 4最终相当于.
但是,如果x首先进行评估,那么我们就会得到6 * 7 * 8 * 9 * …
刚刚在这里学到,-Wsequence-point当代码可以调用UB时,comiplation标志会弹出警告.我在类似的声明上尝试过
int x = 1;
int y = x+ ++x;
Run Code Online (Sandbox Code Playgroud)
它工作得非常好.到目前为止,我已编译gcc或g++仅使用-ansi -pedantic -Wall.你有没有其他有用的标志来使代码更安全和健壮?