此代码是读取和写入ODBC连接的数据库的应用程序的一部分。它在数据库中创建一条记录,然后检查是否已成功创建记录,然后返回true。
我对控制流的理解如下:
command.ExecuteNonQuery()有记录表明,Invalid?Operation?Exception当“方法调用对该对象的当前状态无效”时,将引发。因此,如果发生这种情况,该try块的执行将停止,该finally块将被执行,然后return false;在底部执行。
但是,我的IDE声称该return false;代码不可访问。而且似乎是事实,我可以删除它,并且可以毫无抱怨地进行编译。但是,对我来说,似乎抛出上述异常的代码路径没有返回值。
private static bool createRecord(String table,
IDictionary<String,String> data,
System.Data.IDbConnection conn,
OdbcTransaction trans) {
[... some other code ...]
int returnValue = 0;
try {
command.CommandText = sb.ToString();
returnValue = command.ExecuteNonQuery();
return returnValue == 1;
} finally {
command.Dispose();
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我在这里理解的错误是什么?
请考虑以下声明:
*((char*)NULL) = 0; //undefined behavior
Run Code Online (Sandbox Code Playgroud)
它明确地调用未定义的行为.在给定的程序中是否存在这样的语句意味着整个程序是未定义的,或者一旦控制流命中这个语句,该行为只会变得不确定?
如果用户从未输入数字,3是否可以明确定义以下程序?
while (true) {
int num = ReadNumberFromConsole();
if (num == 3)
*((char*)NULL) = 0; //undefined behavior
}
Run Code Online (Sandbox Code Playgroud)
或者,无论用户输入什么,它都是完全未定义的行为?
此外,编译器是否可以假定在运行时永远不会执行未定义的行为?这样可以及时推理:
int num = ReadNumberFromConsole();
if (num == 3) {
PrintToConsole(num);
*((char*)NULL) = 0; //undefined behavior
}
Run Code Online (Sandbox Code Playgroud)
在这里,编译器可以推断,以防num == 3我们总是调用未定义的行为.因此,这种情况必须是不可能的,并且不需要打印该号码.整个if声明可以优化.根据标准,是否允许这种向后推理?
c++ dead-code undefined-behavior language-lawyer unreachable-code
如果我尝试编译
for(;;)
{
}
System.out.println("End");
Run Code Online (Sandbox Code Playgroud)
Java编译器产生错误说Unreachable statement.但是,如果我添加另一个" 无法访问 "(根据我)break声明并使其成为:
for(;;)
{
if(false) break;
}
System.out.println("End");
Run Code Online (Sandbox Code Playgroud)
它汇编.为什么它不会产生错误?
为什么这段代码没有给出"无法访问的代码"错误?由于布尔值只能为true或false.
public static void main(String args[]) {
boolean a = false;
if (a == true) {
} else if (a == false) {
} else {
int c = 0;
c = c + 1;
}
}
Run Code Online (Sandbox Code Playgroud) 有谁知道原因:
public void foo()
{
System.out.println("Hello");
return;
System.out.println("World!");
}
Run Code Online (Sandbox Code Playgroud)
将被报告为Eclipse下的"无法访问的错误",但是
public void foo()
{
System.out.println("Hello");
if(true) return;
System.out.println("World!");
}
Run Code Online (Sandbox Code Playgroud)
只触发"死代码"警告?
我能想到的唯一解释是Java编译器只标记第一个,而Eclipse中的一些额外分析计算出第二个.但是,如果是这种情况,为什么Java编译器不能在编译时弄清楚这种情况呢?
Java编译器不会在编译时弄清楚if(true)没有效果,从而产生基本相同的字节码吗?在什么时候应用可达代码分析?
我想一个更通用的方法来思考这个问题是:"什么时候应用可达代码分析"?在将第二个Java代码片段转换为最终字节码时,我确信在某些时候删除了"if(true)"运行时等效项,并且两个程序的表示变得相同.然后,Java编译器不会再次应用其可访问的代码分析吗?
我发现了一个案例,我有一些我认为无法访问且未被检测到的代码.编译器和Visual Studio都不会发出警告.
考虑以下代码:
enum Foo { A, B, C }
class Bar { public Foo type; }
static class Program
{
private static void Main()
{
var bar = new Bar { type = Foo.A };
if (bar.type == Foo.B)
{
Console.WriteLine("lol");
}
}
}
Run Code Online (Sandbox Code Playgroud)
显然,程序不会打印出"lol",因为if语句中的条件为false.我不明白为什么没有为无法访问的代码发出警告.我唯一的假设是,如果你在多线程程序中遇到竞争条件,那么这可能是可以达到的.它是否正确?
我在Eclipse中尝试了以下内容:
if (false) {}:警告'死码'while (false) {}:编译错误'无法访问的代码'我想知道这种差异是否存在真正的"原因".我已经发现了......
...但为什么不允许while (false)相同的调试目的?
我得到了很多关于交换机的警告,这些交换机仅部分覆盖了切换的枚举范围.为此,我想有一个"默认"所有这些开关,并将__builtin_unreachable(GCC内置),在这种情况下,让编译器知道这种情况是不可达.
但是,我才知道GCC4.3还不支持内置版.有没有什么好方法可以模仿这个功能?我考虑过取消引用空指针,但这可能有其他不良影响/警告等.你有更好的主意吗?
从一个-5问题再次启发!
我读了@Quartermeister的 [ 评论 ] 并感到惊讶!
那么为什么这会编译
switch(1) {
case 2:
}
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.
int i;
switch(i=1) {
case 2: // Control cannot fall through from one case label ('case 2:') to another
}
Run Code Online (Sandbox Code Playgroud)
这不是
switch(2) {
case 2: // Control cannot fall through from one case label ('case 2:') to another
}
Run Code Online (Sandbox Code Playgroud)
更新:
该-5问题变得-3.
我有这么简单的代码:
public static int GetInt(int number)
{
int[] ints = new int[]{ 3, 7, 9, int.MaxValue };
foreach (int i in ints)
if (number <= i)
return i;
return int.MaxValue; //this should be unreachable code since the last int is int.MaxValue and number <= int.MaxValue is allways true so the above code will allways return
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器说不是每个执行路径都返回一个值.所以我必须编写永远不会达到的代码.我的问题是,在这样的情况下我该怎么办?我应该返回一些默认值还是应该抛出异常.另外,如果我想抛出异常,什么异常适合抛出?我没有找到类似的东西UnreachableCodeException.