编译器通常会提供一个开关,以便在代码无法访问时发出警告.我还看到了一些库的宏,它们为无法访问的代码提供断言.
是否存在提示,例如通过编译指示或内置,我可以传递给GCC(或任何其他编译器),如果确定实际可以达到预期无法访问的行,则会在编译期间发出警告或错误?
这是一个例子:
if (!conf->devpath) {
conf->devpath = arg;
return 0;
} // pass other opts into fuse
else {
return 1;
}
UNREACHABLE_LINE();
Run Code Online (Sandbox Code Playgroud)
这个值的作用是在预期的不可达行之上的条件发生变化之后检测到该行实际上是可达的.
我在下面的代码中的i ++点上在Visual Studio中收到"无法访问代码检测到"消息.你能发现我做错了什么吗?
try
{
RegistryKey OurKey = Registry.CurrentUser;
OurKey.CreateSubKey("Software\\Resources\\Shared");
OurKey = OurKey.OpenSubKey("Software\\Resources\\Shared", true);
for (int i = 0; i < cmbPaths.Items.Count; i++) //<---- problem with i
{
OurKey.SetValue("paths" + i, cmbPaths.Items[i]);
break;
}
}
Run Code Online (Sandbox Code Playgroud) 我是Scala的新手...这是代码:
def ack2(m: BigInt, n: BigInt): BigInt = {
val z = BigInt(0)
(m,n) match {
case (z,_) => n+1
case (_,z) => ack2(m-1,1) // Compiler says unreachable code on the paren of ack2(
case _ => ack2(m-1, ack2(m, n-1)) // Compiler says unreachable code on the paren of ack2(
}
}
Run Code Online (Sandbox Code Playgroud)
我试图理解......为什么会出现这个错误?
注意:我正在使用Scala Eclipse Plugin 2.8.0.r21376-b20100408034031 ch.epfl.lamp.sdt.feature.group
有时在调试时,您无法访问代码片段.无论如何要抑制警告?
我该如何理解这个Java编译器的行为?
while (true) return;
System.out.println("I love Java");
// Err: unreachable statement
if (true) return;
System.out.println("I hate Java");
// OK.
Run Code Online (Sandbox Code Playgroud)
谢谢.
编辑:
几分钟后我发现了这一点:
在第一种情况下,编译器因无限循环而抛出错误.在这两种情况下,编译器都不会考虑语句内部的代码.
编辑二:
让我对javac印象深刻的是:
if (true) return; // Correct
}
while (true) return; // Correct
}
Run Code Online (Sandbox Code Playgroud)
看起来javac知道两个循环内部是什么,如果结果,但是当你编写另一个命令时(如第一个例子中),你得到非等效行为(看起来像javac忘记了循环内部/ if).
公共静态最终EDIT III:
作为此答案我可以此话(希望正确)的结果:作为表达if (arg) { ...; return;}和while (arg) { ...; return;}对Java是等效的两个语义和语法(在字节码)当且仅当argv是不恒定的(或有效最终型)的表达.如果argv是常量表达式字节码(和行为)可能不同.
免责声明
这个问题不是关于无法访问的语句,而是对逻辑等效表达式的不同处理,例如while true return和if true return.
考虑以下 Rust 代码:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable");
}
Run Code Online (Sandbox Code Playgroud)
尽管返回类型是错误的,但它会编译(带有警告)并运行。似乎编译器()对最后一行中的返回类型没有问题,因为它检测到此代码无法访问。
但是,如果我们删除最后一个分号:
fn f() -> i32 {
loop {
println!("Infinite loop!");
}
println!("Unreachable")
}
Run Code Online (Sandbox Code Playgroud)
然后代码不再编译,给出一个类型错误:
error[E0308]: mismatched types
--> src/main.rs:14:5
|
14 | println!("Unreachable")
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()`
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud)
为什么是这样?()在这两个代码片段中,返回类型不是相同的吗?
注意:我有兴趣了解为什么 Rust 编译器在这两个示例上的行为不同,即 Rust 编译器是如何实现的。从语言设计的角度来看,我并不是要问一个关于它“应该”如何表现的哲学问题(我知道这样的问题可能会偏离主题)。
我试图弄清楚是否有任何方法可以避免因预处理器引起的某些事情而出现"无法访问的代码"警告.我不希望禁止所有这样的警告,只有那些将取决于预处理,如
#if WINDOWS
public const GamePlatform platform = GamePlatform.PC;
#else
public const GamePlatform platform = GamePlatform.MAC;
#endif
Run Code Online (Sandbox Code Playgroud)
后来有代码:
if (platform == GamePlatform.PC)
{
...
}
else
{
...
}
Run Code Online (Sandbox Code Playgroud)
这两个部分中的一个将始终被检测为"无法访问的代码",并且我们已经将这些部分全部到位.我想尝试摆脱它创建的许多警告,但我仍然希望得到合法无法访问的代码的警告.(实际上,不仅仅是两个平台,因此每个特定于平台的代码都会产生一堆不必要的警告.)
c# visual-studio-2010 compiler-warnings unreachable-code c-preprocessor
class For1
{
public static void main(String args[])
{
int a = 0;
for(;;)
{
break;
System.out.println(a); //Line 1
++a;//Line 2
}
}
}
Run Code Online (Sandbox Code Playgroud)
我知道第1行/第2行永远不会执行.但我仍然不明白为什么抛出编译时错误.我收到"无法访问的语句"编译错误.
这是否意味着编译器检查它是否能够编译所有分支/代码行?
研究方法如下:
static private void foo() {
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
尽管最后一个catch块实际上无法访问,但此代码编译良好.
现在让评论 throw new FileNotFoundException();行
执行:
哎呀!我们看
Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body
Run Code Online (Sandbox Code Playgroud)
奇怪.为什么java在这些情境中使用双重标准?
static private void foo(FileNotFoundException f) {
try {
throw f;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
工作以及构造函数调用
我注意到在不同版本的java编译器上,我看到编译此代码的不同结果.
public class …Run Code Online (Sandbox Code Playgroud) 我正在开发一个用VC9构建的应用程序,我遇到了一个我不完全理解的警告:为什么在构造函数的右括号上有一个"无法访问的代码"警告?
重现问题的最小测试用例是:
__declspec(noreturn) void foo() {
// Do something, then terminate the program
}
struct A {
A() {
foo();
} // d:\foo.cpp(7) : warning C4702: unreachable code
};
int main() {
A a;
}
Run Code Online (Sandbox Code Playgroud)
必须使用/ W4编译才能触发警告.或者,您可以使用/ we4702进行编译,以强制检测此警告时出错.
d:\>cl /c /W4 foo.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 15.00.21022.08 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
foo.cpp
d:\foo.cpp(7) : warning C4702: unreachable code
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下,究竟是什么在这里无法到达? 我最好的理论是它是析构函数,但我想要一个确定的答案.
如果我想让这段代码警告清洁,我该如何实现呢? 我能想到的最好的是将其转换为编译时错误.
struct A {
private:
A(); // No, you can't construct …Run Code Online (Sandbox Code Playgroud) unreachable-code ×10
java ×4
c# ×2
built-in ×1
c ×1
c++ ×1
constructor ×1
exception ×1
gcc ×1
javac ×1
pragma ×1
return-type ×1
rust ×1
scala ×1
try-catch ×1
visual-c++ ×1