gpt4 book ai didi

Semicolon at end of 'if' statement(‘if’语句末尾的分号)

转载 作者:bug小助手 更新时间:2023-10-25 16:45:28 35 4
gpt4 key购买 nike



Today, after half an hour of searching for a bug, I discovered that it is possible to put a semicolon after an if statement instead of code, like this:

今天,在搜索了半个小时的错误后,我发现可以将分号放在if语句后面,而不是代码后面,如下所示:



if(a == b);
// Do stuff


Which basically means that the stuff will be done whether a equals b or not, and the if statement has no point whatsoever. Why doesn't Java give me an error? Is there any situation in which this would be useful?

这基本上意味着,无论a是否等于b,都会完成,而if语句没有任何意义。为什么Java不给我一个错误呢?在什么情况下,这将是有用的?


更多回答

Looks like a no-op i.e if a is the same as b then do nothing; you could possibly add a javadoc there but I can't think of any other use

看起来像无操作,即如果a与b相同,则不执行任何操作;您可以在那里添加一个javadoc,但我想不出还有什么其他用途

no, there is no situation for this to be useful. why? if I got a dime for every thing I don't understand in Java :)

不,没有任何情况下这是有用的。为什么?如果我对Java中的每一件不理解的事情都能得到一毛钱:)

The general rule is semicolon(;) completes the statement. So nothing happens after that if

一般规则是用分号(;)结束语句。所以在那之后什么都不会发生

Aha! This is the kind of fault that the Python syntax - with visual indentation showing block extents, that makes this kind of error less likely to happen in Python as, in general, if a block of code is not indented to be with in an if statement, then it isn't in the if statement.

啊哈!这就是Python语法的错误类型--使用显示块范围的可视缩进,这使得此类错误不太可能在Python中发生,因为通常情况下,如果代码块没有缩进以便在if语句中使用,那么它就不会在if语句中使用。

@gefei : there is no situation for this to be useful, true. But there can be situation(s) where this can(or be used to) impact the program. please see my answer.

@Gefei:没有任何情况下这是有用的,真的。但在某些情况下(S),这可能会(或被用来)影响节目。请看我的回答。

优秀答案推荐

Why does it happen?


Java Language Specification says that:

Java语言规范规定:



The Empty Statement


An empty statement does nothing.


EmptyStatement:
;

Execution of an empty statement always completes normally



It essentially means that you want to execute empty statement if a==b

它本质上意味着如果a==b,您想要执行空语句


if(a == b);

What should you do:


There are two main solutions to this problem:

这个问题有两种主要的解决方案:



  1. You can avoid problems with empty statement by using code formatter
    and surrounding stuff inside if with { and }. By doing this
    Your empty statement will be much more readable.


    if(a == b){
    ;
    }


  2. You can also check tools used for static code analysis such as:




    They can instantly highlight problems such as this one.




I would recommend to combine both solutions.

我建议将这两种解决方案结合起来。




Is there any situation in which this would be useful?




Useful? As in "makes your code cleaner, clearer, faster, more maintainable"? Not at all. This is most likely poor, confusing code.

有用吗?比如“让你的代码更干净、更清晰、更快、更易维护”?不用谢。这很可能是糟糕的、令人困惑的代码。



But it's not necessarily benign. Such a statement can perform actions and/or alter state due to methods which cause side effects, and optionally evaluate those methods due to short-circuiting of operators.

但这并不一定是良性的。这样的语句可以执行由于引起副作用的方法而导致的动作和/或改变状态,并且可选地评估由于操作符短路而导致的那些方法。



if( a() && b() );


Here, a() or b() may do something, and b() will only execute if a() is true.

在这里,a()或b()可以做一些事情,而b()只有在a()为真时才会执行。



As to why, I think the answer is simply that it would be worse to deviate from defined, expected behavior (e.g. statements like while(reader.read());) than the alternative of developers writing bad code.

至于原因,我认为答案很简单,偏离定义的、预期的行为(例如,像While(Reader.Read());这样的语句)将比开发人员编写糟糕代码的替代方案更糟糕。



Writing bad code is always possible. And just to reiterate, this would be bad code in almost any case.

编写错误的代码总是有可能的。我只想重申,这几乎在任何情况下都是糟糕的代码。



A possible use case:

一个可能的用例:



if (a==b);
else {
// Do something
}


Not good, but possible.

不好,但有可能。



Still, I do think that the Java specification should disallow an empty if.

不过,我确实认为Java规范不应该允许空的if。



If you're using Eclipse, you can make it warn you about those statements:

如果您使用的是Eclipse,您可以让它警告您这些语句:



Java->Compiler->Errors/Warnings



If you use an if statement, the first statement after the if will be executed if the condition is true. If you have a block after the if (with curly braces), it counts for that whole block. If there is no block it counts for only one statement. A single semicolon is an empty statement. You could also write the code from you example like this:

如果使用If语句,则在条件为真的情况下将执行If之后的第一条语句。如果在if后面有一个块(带大括号),它将计入整个块。如果没有块,则它只计为一条语句。单个分号是空语句。您还可以从您的示例编写代码,如下所示:



if(a==b) {
;
}


It is an old leftover from the days when there was more syntactic sugar to differentiate expressions from statements.

这是一种古老的遗留下来的东西,当时有更多的句法糖来区分表达和陈述。



Basically, the comma was used as the list item separator, so the semicolon was used as the "list of statements" separator. The downside is in the handling of null items in lists, and null statements in blocks.

基本上,逗号被用作列表项分隔符,因此分号被用作“语句列表”分隔符。缺点是处理列表中的空项和块中的空语句。



In a list of items, Java uses the explicit keyword null, but a "null statement" is just an empty line. Allowing the existence of an empty line is a holdover from tradition inherited from C.

在项目列表中,Java使用显式关键字NULL,但“NULL语句”只是一个空行。允许空行的存在是从C语言继承的传统的保留。



Why do it? Especially with an if statement when you know that no statements are being executed: Because some if statements have side effects:

为什么要这么做?尤其是在知道没有执行任何语句的情况下使用IF语句:因为有些IF语句有副作用:



 int c;
if ((c = in.read()) != -1);


Yes, it is not the best example, but basically it says read a byte from the stream and do nothing. Might be useful in some corner cases, but even if this example isn't the best, it illustrates the intent. We want to feel the side-effects of the expression without accidentally executing any statements.

是的,这不是最好的例子,但基本上它是说从流中读取一个字节,然后什么都不做。在某些情况下可能很有用,但即使这个示例不是最好的,它也说明了意图。我们希望在不意外执行任何语句的情况下感受到表达式的副作用。



I can't think of an occasion where it is useful. It can be useful for loops like

我想不出有什么场合它是有用的。它对于像这样的循环很有用



 while(do something);


or



 for(init; do something; something else);


If you use your code formatting in your IDE regularly these sort of bugs become obvious. Some IDEs highlight this as a probable bug as well.

如果您经常在IDE中使用代码格式,这些类型的错误就会变得很明显。一些IDE也强调这是一个可能的错误。



I'd agree with you there's no useful purpose to this for a human. I suspect it's there because it simplifies the language definition; it means that the thing that comes after an if is e same as the thing that comes after a while, for instance.

我同意你的观点,这对人类来说没有任何用处。我怀疑它的存在是因为它简化了语言定义;例如,它意味着if后面的东西和一段时间后的东西是一样的。



Why? It's because its easier for compiler writers. You don't have to make a special case to check for semicolons after if(cond) and has an added usage of allowing

为什么?这是因为这对编译器编写人员来说更容易。您不必在if(Cond)之后使用特殊情况来检查分号,并且增加了允许的用法



if (cond && maybeFunc())
;// Code here I want to ignore


Even though it's actually a terrible idea to allow this. It's just easier to allow and then to add a case to check this.

尽管允许这样做实际上是个糟糕的主意。只是更容易允许然后添加一个案例来检查这一点。



Java allows an empty block any place a statement block is allowed. I am sure making this a general rule for all blocks simplifies the compiler.

Java允许空块出现在任何允许语句块的地方。我确信将其作为所有块的通用规则可以简化编译器。



I agree that this is primarily the cause of bugs that are spectacularly hard to find. I always use braces around blocks, even when there is a single statement, but Java allows you to make a block with braces at any point, so using braces can not save you from this fate. For example, I once wasted 4 hours trying find something like this:

我同意这主要是很难找到的错误的原因。我总是在块周围使用大括号,即使只有一条语句,但Java允许您在任何位置使用大括号来创建块,所以使用大括号并不能使您免于这种命运。例如,我曾经花了4个小时寻找这样的东西:



while (condition);
{
statement;
statement;
}


The semicolon at the end of the first line was a typo, accidentally making the statement block for the while loop empty. Because the syntax is valid the program compiled and ran fine, just not the way I wanted it to. It was really hard to find.

第一行末尾的空格是一个打字错误,意外地使while循环的语句块为空。因为语法是有效的程序编译和运行良好,只是不是我想要的方式。很难找到。



I can think of one situation where it is very nice that you are allowed to have empty blocks, and this is something like this:

我能想到一种情况,允许你有空块是非常好的,这是这样的:



if (condition1) {
do_action_1();
}
else if (condition2) {
//nothing really to do in this case
}
else if (condition3) {
do_action2();
}
else {
do_action3();
}


In the above example, you want to be able to separate out various conditions. Remember, those conditions might be overlapping, so it is not always possible to rearrange the order. If one of the conditions really does not need anything done, then it is nice that Java allows you to have an empty block. Otherwise, the language would need some form of a "noop" method to use when you really do not want anything done.

在上面的例子中,您希望能够区分不同的条件。请记住,这些条件可能是重叠的,因此并不总是可能重新安排顺序。如果其中一个条件确实不需要做任何事情,那么Java允许您拥有一个空块是很好的。否则,当您真的不想做任何事情时,该语言将需要使用某种形式的“noop”方法。



I personally would prefer the explicit "noop" statement -- but that is not how Java is defined.

我个人更喜欢明确的“noop”语句--但Java不是这样定义的。



Just a FYI about the usability and what difference it makes or can make if there is a statement like that

仅供参考,关于可用性,以及如果有这样的声明,它会产生什么影响或可以产生什么影响



Consider a piece of code like the following.

考虑如下所示的一段代码。



int a = 10;
if ((a = 50) == 50);

System.out.println("Value of a = " + a);


Clearly in this case, the if statement does change the output. So a statement like that can make a difference.

显然,在本例中,if语句确实更改了输出。因此,这样的声明可以产生不同的影响。



This is a situation where this could be useful or better to say have an impact on program.

这是一种情况,在这种情况下,这可能是有用的,或者更好地说对计划产生影响。



if(a==b)
println("a equals b");


You can use an IF statement without {} if there is only a single line to be executed, so by using if(a==b); you are saying if they equal, execute and empty statement... So it will do nothing, and then return to your normal loop, outside of the IF block.

如果只有一行要执行,你可以使用不带{}的IF语句,所以通过使用if(a==b);你是说如果它们相等,执行和空语句.所以它什么也不做,然后返回到IF块之外的正常循环。



A few definitions from the jls explain this (chapter 14):

JLS中的几个定义解释了这一点(第14章):



Blocks are Statements



As stated here, a Block is a StatementWithoutTrailingSubstatement, which in turn is a StatementNoShortIf, which is a Statement. Thus where ever any of these is required, we can insert a Block.

如此处所述,块是一条StatementWithoutTrailingSub语句,而后者又是一条StatementNoShortIf,即一条语句。因此,在任何需要这些的地方,我们都可以插入一个块。



The if-clause



Though this is as well the case for for and while-loops, I'll use if-statements. These rules are pretty much the same. The syntactical description of if-statements can be found here.

虽然这也适用于for和While-循环,但我将使用if-语句。这些规则大同小异。IF语句的句法描述可以在这里找到。



IfThenStatement:
if ( Expression ) Statement

IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement

IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf


So we can use our block here.

所以我们可以在这里使用我们的街区。



But why does it work with ; ?



; is defined as the EmptyStatement (link), which is as well a StatementNoShortIf. So in conditional pieces of code, like if-statement and loops, we can replace a Block with a EmptyStatement, if a StatementNoShortIf or Statement is required.

定义为EmptyStatement(Link),它也是一个StatementNoShortIf。因此,在条件代码片段中,如If-Statement和循环,如果需要StatementNoShortIf或语句,我们可以用EmptyStatement替换Block。



Thus if(Expression)EmptyStatement works.

因此,if(表达式)EmptyStatement起作用。



Why doesn't this give an error?



Pretty simple: java gives an error if it finds invalid syntax. But if(Expression)EmptyStatement is perfectly valid syntax. Instead javac gives a warning if launched with the proper parameters. The full list of warnings that can be dis-/enabled lists the warning-name empty for this purpose. So compilation with -Xlint:all or -Xlint:empty will generate a warning about this.

非常简单:如果Java发现无效语法,它会给出一个错误。但是if(表达式)EmptyStatement是完全有效的语法。相反,如果使用正确的参数启动,则javac会发出警告。可以取消/启用的警告的完整列表列出了为此而空的警告名称。因此,使用-Xlint:All或-Xlint:Empty进行编译将生成有关此问题的警告。



Your IDE should have an option to enable this kind of warning as well.
For eclipse, see @nullptr's answer. In IntelliJ, you can press Ctrl + Shift + A, enter empty body into the search field and enable the warning (marked in the image)

您的IDE也应该具有启用此类警告的选项。有关eclipse,请参阅@nullptr的答案。在IntelliJ中,您可以按Ctrl+Shift+A,在搜索字段中输入空体并启用警告(如图所示)



IntelliJ enable empty-body warning



What is this even used for?



To be honest, there's not much use in it from a minimalistic point of view. There's usually a way to get things done without a "do nothing" command. It's rather a question of personal preferences, whether you rather use

老实说,从极简主义的角度来看,它并没有多大用处。通常有一种方法可以在没有“什么都不做”命令的情况下完成任务。这是个人喜好的问题,你是否愿意使用



if( a() && b() );


or



if( a() ) b();


and same would apply to other cases, in which the EmptyStatement is used. An important point to consider on this topic is readability of code. There are occasions, where code becomes more readable by using the no-op. On the other hand there are cases, where code becomes quite a lot harder to comprehend with using the EmptyStatement - the above example would count to the later IMO.

同样的情况也适用于其他使用EmptyStatement的情况。关于此主题,需要考虑的一个重要问题是代码的可读性。在某些情况下,使用no-op使代码变得更具可读性。另一方面,在某些情况下,使用EmptyStatement会使代码变得更难理解--上面的示例将计入后面的IMO。



I can think of a scenario where an empty statement is required (not for if condition but for while loop).

我能想到一个需要空语句的场景(不是for if条件,而是for While循环)。



When a program just want an explicit confirmation from the user to proceed. This may be required when the work after the user confirmation depends on some other things and user want to take control of when to proceed.

当程序只需要来自用户的明确确认才能继续时。当用户确认后的工作取决于某些其他事情,并且用户想要控制何时继续时,可能需要这样做。



    System.out.println("Enter Y to proceed. Waiting...");
System.out.println("");

while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));

System.out.println("Proceeding...");
// do the work here


look this:

看看这个:



int a,b,c = 0;
if(a == b){
c =1;
}
System.out.print(c);//1


so, you can write like this:

因此,您可以这样写:



if (a == b)c=1;


but,if this code is this:

但是,如果代码是这样的:



int a,b,c=0;
if (a != b){
}
if (a == b ){
c =1;
}


you can write like this:

您可以这样写:



if(a != b);
if(a == b )c=1;


so,you will know if(a != b); do noting

所以,你会知道如果(a!=b);什么都不做



The semi-colon in the if indicates the termination of the if condition as in java ; is treated as the end of a statement, so the statement after if gets executed.

if中的分号表示if条件的终止,就像在java中一样;被视为语句的结束,所以if之后的语句被执行。



Semicolon at the end of,

if(a==b); simply finish the statement in single line which means ignore the result of condition and continue the execution from the next line

This code is useful, on the other hand sometime introduce bug in program, for example,


case 1.


a = 5;

b = 3;

if(a == b);

prinf("a and b are equal");


case 2.


a = 5;

b = 5;

if(a == b);

prinf("a and b are equal");

would print the same output on the screen...

在语句末尾加上分号if(a==b);只需在一行中结束语句,表示忽略条件的结果并从下一行继续执行此代码很有用,但有时会在程序中引入错误,例如,情况1.a=5;b=3;if(a==b);prinf(“a和b等于”);情况2.a=5;b=5;if(a==b);prinf(“a和b等于”);是否会在屏幕上打印相同的输出...



While working on a programming assignment for class where I am working with a N by N grid of doodads and comparing characteristics of a random doodad to those above, below, left, and right, I found a nice use of this to prevent nested statements and potential boundary exceptions. My goal was to minimize code and keep from nesting if-statements.

在为类进行编程作业时,我正在处理一个N乘N的doodad网格,并将随机doodad的特征与上面、下面、左边和右边的那些进行比较,我发现使用这种方法可以很好地防止嵌套语句和潜在的边界异常。我的目标是最大限度地减少代码,避免嵌套if语句。



if (row == 0); 
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));


where method(Doodad a, Doodad b) does some operation between a and b.

其中方法(Doodad a,Doodad b)在a和b之间执行一些操作。



Alternatively, you could use exception handling to avoid this syntax, but it works and works well for my application.

或者,您可以使用异常处理来避免这种语法,但它非常适用于我的应用程序。


更多回答

Even the simplest solution, using a code formatter, would deal with this problem. The statement that was intended to be inside the if would have appeared at the same indentation as the if.

即使是最简单的解决方案,使用代码格式化程序,也可以处理这个问题。原本要放在IF中的语句将以与IF相同的缩进形式出现。

Sure, but I recommend to use both formatter and static code analysis.

当然可以,但我建议同时使用格式化程序和静态代码分析。

You CAN'T avoid this by using the braces, because an accidental semicolon after the close paren, and before the open brace, is a syntactically valid program ... and probably not what you wanted. I agree however that a code for matter might help avoid this problem.

您不能通过使用大括号来避免这一点,因为在结束Paren之后和左大括号之前意外地使用分号是一个语法有效的程序...可能也不是你想要的。然而,我同意物质的代码可能有助于避免这个问题。

Code like this can actually prevent errors in logic by accounting for all cases. "If true do nothing, else..." can be more readable since you don't get confused by negation mistakes and a "missing case". Most compilers these days are aware of this construct and invert for you anyway for a speed improvement. e.g. The Mercury language enforces this!

这样的代码实际上可以防止逻辑中的错误,因为它考虑了所有情况。“如果是真的,什么都不做,其他的.”可读性更好,因为您不会被否定错误和“缺少大小写”所迷惑。如今,大多数编译器都意识到了这种构造,并不管怎样都会为您进行倒置以提高速度。例如,水星语言强制执行这一点!

@tudor I would say even for that use case, it'd be better to do if (a==b) { // do nothing } else { doSomething(); }, since it's more obvious that the no-op is on purpose and not a typo.

@Tudor我会说,即使对于那个用例,如果(a==b){//什么都不做}其他的{DoSomething();}会更好,因为更明显的是,no-op是故意的,而不是拼写错误。

@yshavit That's true. Comments help to make things clearer alot of the time, but that's different to this construct. Besides, there's no functional difference between if (a==b); //do nothing and if (a==b) { /*do nothing*/ } Both will be optimised out by removing the comment and empty case and inverting the conditional.

@yshavit这是真的。注释在很大程度上有助于使事情变得更清楚,但这与这种构造不同。此外,If(a==b);//Do Nothing和If(a==b){/*Do Nothing*/}之间没有函数差异,两者都将通过删除注释和空格并颠倒条件进行优化。

@tudor For a compiler, yes, no question about that. But let me put it this way: If I saw someone do it my way, I would figure "this person must have thought it's easier to express the condition this way." If I saw them using the semicolon+else-braces syntax, I would check the VCS logs to make sure it wasn't a typo/bug to which someone else later added an else clause.

@Tudor对于编译器来说,是的,这是毫无疑问的。但让我这么说吧:如果我看到有人按照我的方式做,我会想:“这个人一定认为用这种方式表达条件更容易。”如果我看到它们使用分号+Else-花括号语法,我会检查VCS日志,以确保这不是别人后来添加了Else子句的拼写错误/错误。

+1, but usage example is unnecessary. As you show it can be used, but it's far from the best way to organize that code. It's ugly, but there's no reason to special case it in order to reject -- at least from the compiler's POV. From a stle POV...

+1,但不需要用法示例。正如您所展示的,它是可以使用的,但它远不是组织该代码的最佳方式。它很难看,但没有理由为了拒绝它而对其进行特殊处理--至少从编译器的POV来看是这样。来自一个Stle POV。

println("a now equals b");

Println(“a现在等于b”);

"This code is useful" <- How could it be useful to ignore the result of a condition?

“这段代码很有用”<--忽略条件的结果怎么会有用呢?

yes it is, in if-elseif hierarchy if we required to ignore the result of certain condition this could be use. for example

是的,如果我们需要忽略某些条件的结果,在If-Elseif层次结构中可以使用它。例如

if(row != 0) method (grid[row][col], grid[row-1][col]); would have the same effect without using empty if statements.

If(row!=0)方法(GRID[ROW][COL],GRID[ROW-1][COL]);在不使用空IF语句的情况下也会有相同的效果。

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com