ANSI标准是否要求逻辑运算符在C或C++中被短路?
我很困惑,因为我记得K&R的书说你的代码不应该依赖于这些操作被短路,因为它们可能没有.有人可以指出标准中的哪个位置逻辑操作始终是短路的吗?我最感兴趣的是C++,C的答案也很棒.
我还记得读(不记得在哪里)评估顺序没有严格定义,所以你的代码不应该依赖或假设表达式中的函数将按特定的顺序执行:在语句的末尾所有引用的函数将被调用,但编译器可以自由选择最有效的顺序.
标准是否表明该表达式的评估顺序?
if( functionA() && functionB() && functionC() ) cout<<"Hello world";
Run Code Online (Sandbox Code Playgroud) c c++ operator-precedence short-circuiting logical-operators
为什么这个程序打印"分叉!"4次?
#include <stdio.h>
#include <unistd.h>
int main(void) {
fork() && (fork() || fork());
printf("forked!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud) 据我所知,逻辑运算符的&&优先级高于||.在运行代码时:
#include <stdio.h>
int main()
{
int i = 1, j =1, k = 1;
printf("%d\n",++i || ++j && ++k);
printf("%d %d %d",i,j,k);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给出输出:
1
2 1 1
Run Code Online (Sandbox Code Playgroud)
只有在这样++i || ++j && ++k评估时才有可能:
(++i) || (++j && ++k)
Run Code Online (Sandbox Code Playgroud)
但是,根据运算符优先级规则,它应该被评估为:
(++i || ++j) && (++k)
Run Code Online (Sandbox Code Playgroud)
因此输出应该是:
1
2 1 2
Run Code Online (Sandbox Code Playgroud)
这有什么问题?
注意:根据我的理解,我认为具有更高优先级的运算符如下评估(如果它是左关联的):
1.评估其左表达式
2.然后评估其正确的表达式(如果需要)
我错了吗?
我在其中一个论坛上看到过这段代码,我发现很难找到给定代码的输出.我真的很困惑,我该如何解决这条特殊的线?
fork() && fork() || fork();
Run Code Online (Sandbox Code Playgroud)
#include <stdio.h>
#include <unistd.h>
int main()
{
fork();
fork() && fork() || fork();
fork();
printf("forked\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有一个关于编译器如何评估c中"AND"条件的问题.
说,我写一个声明就好
if( (today is Thursday) && (Month is July) )
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
假设今天不是星期四,但月份确实是七月.
编译器是否检查两个条件,并执行1&0 == 0?或者,一旦它看到今天不是星期四,它就会跳过,甚至不用费心去查看月份情况,因为它无关紧要.
我正在使用以下gcc
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Run Code Online (Sandbox Code Playgroud) 给定C++函数foo:
bool foo();
Run Code Online (Sandbox Code Playgroud)
以及以下代码行
bool some_bool = false;
some_bool = some_bool and foo();
Run Code Online (Sandbox Code Playgroud)
我观察到foo()虽然它可能有副作用,但没有被调用.这种行为的名称是什么,它是否依赖于编译器?
我的代码中有以下行:
1 || printf("A");
Run Code Online (Sandbox Code Playgroud)
我很惊讶地看到A没有打印; 我猜这是由于编译器优化:1被评估为真,并且,因为整个OR表达式必须是真的,printf("A")甚至没有评估...有人可以证实这一点吗?使用不同的编译器,程序会表现得像这样吗?
我在下面给出的程序中输出为0..0.为什么在检查条件时j不会增加?
int main(int argc, char const *argv[])
{
int i=0,j=0;
if(i&&j++)
printf("%d..%d",i++,j);
printf("%d..%d",i,j);
return 0;
}
Run Code Online (Sandbox Code Playgroud)