为什么在空 "while" 循环中没有关于可能错误的空语句的警告?
Why is there no warning about a possible mistaken empty statement in an empty "while" loop?
有 吨 篇关于 compiler warning CS0642: "Possible mistaken empty statement" 的帖子,我了解它的全部内容。例如,未使用 FileStream
实例 f
,因此这可能是一个错误:
using (var f = File.OpenRead("f.txt")) ; // Possible mistaken empty statement
但是,此 while
语句 不会 产生警告,即使 x
没有机会变得等于或大于 3
。为什么?
int x = 1;
while (x < 3) ; // why no warning?
这是一个存在警告但 Timer
实例 t
实际上 可以 做某事的示例,即触发回调:
using (var t = new Timer((x) => Debug.Print("This"), null, 500, 500)) ; // warning
为什么不一致?
没有不一致。 CS0642 不是关于验证您的代码是否有意义或是否曾经执行过,它只是为了捕捉一些可能代表错误的语法模式。比较:
int x = 1;
while (x < 3) {} // no warning
while (x < 3); {} // CS0642
if (x < 3) ; // CS0642
using (new object() as IDisposable) ; // CS0642
using (new object() as IDisposable) {} // no warning
for (; x < 3 ;) ; // empty statement *and* condition is always true, still no warning
用单个 ;
而不是 { }
编写空循环是程序员带来的常见 C 习惯用法(无论好坏);让这些总是触发 CS0642 可能会产生太多误报。然而,using
从来都不是 C 惯用语,因此强制始终将空块写成 { }
似乎是合理的。它肯定会捕捉到一些你可能会弄错的情况:
TextWriter x = null;
using (x) ; // CS0642
x.WriteLine(); // whoops, use of disposed object
不可否认,这不是一个可能的模式,即使是在块中包装单个语句也是一种很好的做法——即使在 C 中也是如此。
顺便说一句,如果由 Eric Lippert 决定,根本就没有 ;
,到处都是 { }
:
The empty statement feature is redundant, rarely needed, and
error-prone, and it creates work for the compiler team to implement a
warning telling you not to use it. The feature could simply have been
cut from C# 1.0.
(Source.)
一个后续问题是为什么 C# 编译器没有明显努力警告任何总是 true
或 false
的重要条件,这是一个相当普遍的特征C 编译器。编译器对始终为 true
或 false
(如 CS0464、"Comparing with null of type 'type' always produces 'false'")但不是一般表达式的表达式有 一些 警告。这背后可能有一个设计决定,我什至可能看过一次 Eric Lippert 的博客——或者我只是想象那个。无论如何,没有得到警告与CS0642无关。
有 吨 篇关于 compiler warning CS0642: "Possible mistaken empty statement" 的帖子,我了解它的全部内容。例如,未使用 FileStream
实例 f
,因此这可能是一个错误:
using (var f = File.OpenRead("f.txt")) ; // Possible mistaken empty statement
但是,此 while
语句 不会 产生警告,即使 x
没有机会变得等于或大于 3
。为什么?
int x = 1;
while (x < 3) ; // why no warning?
这是一个存在警告但 Timer
实例 t
实际上 可以 做某事的示例,即触发回调:
using (var t = new Timer((x) => Debug.Print("This"), null, 500, 500)) ; // warning
为什么不一致?
没有不一致。 CS0642 不是关于验证您的代码是否有意义或是否曾经执行过,它只是为了捕捉一些可能代表错误的语法模式。比较:
int x = 1;
while (x < 3) {} // no warning
while (x < 3); {} // CS0642
if (x < 3) ; // CS0642
using (new object() as IDisposable) ; // CS0642
using (new object() as IDisposable) {} // no warning
for (; x < 3 ;) ; // empty statement *and* condition is always true, still no warning
用单个 ;
而不是 { }
编写空循环是程序员带来的常见 C 习惯用法(无论好坏);让这些总是触发 CS0642 可能会产生太多误报。然而,using
从来都不是 C 惯用语,因此强制始终将空块写成 { }
似乎是合理的。它肯定会捕捉到一些你可能会弄错的情况:
TextWriter x = null;
using (x) ; // CS0642
x.WriteLine(); // whoops, use of disposed object
不可否认,这不是一个可能的模式,即使是在块中包装单个语句也是一种很好的做法——即使在 C 中也是如此。
顺便说一句,如果由 Eric Lippert 决定,根本就没有 ;
,到处都是 { }
:
The empty statement feature is redundant, rarely needed, and error-prone, and it creates work for the compiler team to implement a warning telling you not to use it. The feature could simply have been cut from C# 1.0. (Source.)
一个后续问题是为什么 C# 编译器没有明显努力警告任何总是 true
或 false
的重要条件,这是一个相当普遍的特征C 编译器。编译器对始终为 true
或 false
(如 CS0464、"Comparing with null of type 'type' always produces 'false'")但不是一般表达式的表达式有 一些 警告。这背后可能有一个设计决定,我什至可能看过一次 Eric Lippert 的博客——或者我只是想象那个。无论如何,没有得到警告与CS0642无关。