诊断(续)[英] Diagnostics (continued)

问题描述

考虑一下这个不错的 C 程序:

短长n;
有符号无符号b;
const long const long a;
无符号双w;
有符号浮点数 k;
短双q;
unsigned long double z;

我很惊讶我亲爱的 lcc-win 非常糟糕的诊断信息
为那些错误写的.

更正之后,我通过 MSVC 传递了这段代码,它
为所有这些错误写了一个正确的诊断......除了
最后一个.

unsigned long double 合法吗?

我有严重的疑问.

此外,MSVC 仅对重复的限定符发出警告,例如
"const long const long"……这不是错误吗?

gcc 为所有这些都写了正确的诊断,而且都是错误,
不是警告.

PellesC 错过了"const long const long";完全,但是错误
就像我所拥有的那样:只是"无效的类型规范";而不是一个
更具体的错误.

--
雅各布·纳维亚
jacob 在 jacob 点 remcomp 点 fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32

推荐答案

jacob navia <ja***@nospam.com 写道:
考虑一下这个不错的 C 程序:

短长n;
有符号无符号b;
const long const long a;
无符号双w;
有符号浮点数 k;
短双q;
unsigned long double z;

我很惊讶我亲爱的 lcc-win 非常糟糕的诊断信息
为那些错误写的.

更正之后,我通过 MSVC 传递了这段代码,它
为所有这些错误写了一个正确的诊断......除了
最后一个.

unsigned long double 合法吗?

我有严重的疑问.
不,"unsigned long double"是违反约束的,你可以
通过重新阅读 C99 6.7.2,类型说明符进行验证.
此外,MSVC 仅对重复的限定符发出警告,例如
"const long const long"……这不是错误吗?
不,类型 *specifiers* 不能重复(除了"long long"和
变体),但输入 *qualifiers* 例如"const";可能会重复,所以
"const long const long"相当于"const long long".(这是
虽然丑陋,所以警告似乎是合适的,虽然它不是
必填.)

C99 6.7.3p4:

如果同一个限定符在同一个
中出现多次_specifier-qualifier-list_,直接或通过一个或多个
typedefs,行为​​与只出现一次相同.

我认为这个想法是,如果你有一个"const int"的 typedef,你
仍然可以应用"const";到 typedef:

typedef const int c_int;
常量 c_int x = 42;

(恕我直言,"const"属于对象声明,而不是埋在一个
typedef,但语言允许.)

无论如何,如你所知,标准并没有区分
错误和警告.不会导致翻译失败的警告
仍然可以是有效的"诊断消息";按照标准的要求.
gcc 为所有这些都写了正确的诊断,而且都是错误,
不是警告.
好的,但许多 gcc 所需的诊断都是警告.
PellesC 错过了"const long const long";完全地,
可能是因为它是有效的.
但是错误
就像我所拥有的那样:只是"无效的类型规范";而不是一个
更具体的错误.
我不觉得需要更具体的错误信息,
但这取决于你.

--
基思·汤普森 (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
诺基亚
"我们必须做点什么.这是东西.因此,我们必须这样做."
-- Antony Jay 和 Jonathan Lynn,"是的部长"

Keith Thompson 说:
雅各布·纳维亚 <ja***@nospam.com 写道:
<剪辑>
>
>此外,MSVC 仅针对重复限定符发出警告,例如
"const long const long"……这不是错误吗?

不,类型 *specifiers* 不能重复(除了"long long"和
变体),但输入 *qualifiers* 例如"const";可能会重复,所以
"const long const long"相当于"const long long".(这是
虽然丑陋,所以警告似乎是合适的,虽然它不是
必填.)

C99 6.7.3p4:

如果同一个限定符在同一个
中出现多次_specifier-qualifier-list_,直接或通过一个或多个
typedefs,行为​​与它只出现一次一样.
或许值得注意的是,这是从 C90 的一个变化,其中
重复类型限定符是违反约束的:

"同一个类型限定符在同一个中不能出现多次
说明符列表或限定符列表,直接或通过一个或多个
typedef s."

<截图>

--
理查德·希思菲尔德 <http://www.cpax.org.uk>
电子邮件:-http://www.+rjh@
谷歌用户:<http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet 是个奇怪的地方"- dmr 1999 年 7 月 29 日

Richard Heathfield <rj*@see.sig.invalidwrites:
雅各布·纳维亚 说:
[...]
>此外,MSVC 仅针对重复限定符发出警告,例如
"const long const long"……这不是错误吗?

这是违反约束的,需要诊断消息.看来
在这种情况下,MSVC/does/发出诊断消息,这很好.
正如 elsethread 所讨论的,它在 C90 中是违反约束的,但在
中没有C99.(我好像记得MSVC不支持,或者声称不支持
支持,C99.)不管怎样,警告意味着他们没事.至少,
它*可能*会;见下文.
>gcc 为所有这些都写了正确的诊断,而且都是错误,
不是警告.

该标准没有区别.该标准使用术语"诊断"
消息".错误和警告实际上只是白话.
>PellesC 错过了"const long const long";完全,但错误
和我一样:只是"无效的类型规范";而不是
更具体的错误.

只要产生诊断消息,就不是一致性
问题.
从原来的问题有点离题...

C99 定义了一个"诊断消息".作为"属于一个
的消息实现的消息输出的实现定义的子集".

C99 5.1.1.3 说:

一个符合要求的实现应产生至少一个诊断
消息(以实现定义的方式标识)如果一个
预处理翻译单元或翻译单元包含一个
违反任何语法规则或约束,即使行为
也明确指定为未定义或
实现定义.不需要生成诊断消息
其他情况.

带有(非规范性)脚注:

目的是实现应该识别性质
并在可能的情况下定位每个违规行为.当然,一个
实现可以免费生成任意数量的诊断,如
只要一个有效的程序仍然被正确翻译.还可以
成功翻译无效程序.

直到现在还没有完全理解的是"诊断信息".是
实现的消息输出的*子集*,以及
需要实现来记录哪些消息是诊断性的.

非常严格地说,一条消息说"违反约束
第 42 行"如果实现的文档是不够的
并不是说那是"诊断信息".

更现实地说,一个实现可以在其文档中说
警告(可能以"警告:"开头的消息)不会
算作"诊断信息";标准含义内.
意图是所有语法错误和约束违规
产生实际的错误消息,而不仅仅是警告.(<OT>gcc 明显
没有这样的政策.</OT>)

换句话说,标准不区分警告和
错误消息,但实现可能会以这样的方式这样做:
区别很重要.

如果有这样的实现,针对这个:
常量 int 常量 x = 42;
打印这个:
警告:多余的"const";限定词
那么这将是 C90 的一致性失败(但不是 C99,
这允许冗余的"const";限定符).

我不知道实际实现如何定义"诊断"
消息".

--
基思·汤普森 (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
诺基亚
"我们必须做点什么.这是东西.因此,我们必须这样做."
——安东尼·杰伊和乔纳森·林恩,"是的部长"

本文地址:https://www.itbaoku.cn/post/1050735.html