欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 手游 > (C23/C++23) 语句末尾的标签

(C23/C++23) 语句末尾的标签

2024/10/24 20:17:57 来源:https://blog.csdn.net/CUBE_lotus/article/details/140702391  浏览:    关键词:(C23/C++23) 语句末尾的标签

文章目录

  • 🔖前言
    • 🏷️ref
    • 🏷️标号
  • 🔖兼容
    • 🏷️23标准前
    • 🏷️23标准后
    • 🏷️原因
  • 🔖未兼容
  • 🔖END
    • 🌟关注我

🔖前言

🏷️ref

  • C++23提案·复合语句末尾的标签
    • p2324r2.pdf (open-std.org)
  • C23提案·声明和语句块结束前的标签
    • n2508.pdf (open-std.org)

在C/C++的标签使用语法中,两们语言的规定并不是一致的。很容易产生写法A在C语言中可行,而C++中不行。(虽然部分编译器做了增强,但标准中就是不行)。

但非常幸运的是两者都在23标准中互相做了兼容。

个人猜测是那帮专家自己写要兼容的代码时觉得非常麻烦而提出的。

因为标签的意义就是一个表示,且表示非常明确,编译器理应本身就能做区分。

🏷️标号

任何语句都能有标号,通过在语句自身前提供一个跟随冒号的名称。

任何语句(但非声明)可以前附任意数量的标号,每个都声明一个 标识符 为标号名,标号名必须在闭合的函数中唯一(换言之,标号名拥有函数作用域)。

标号声明自身没有效果,不会以任何方式变更控制流,或修改跟随其后的语句的行为。

🔖兼容

🏷️23标准前

下面是一个典型的例子。此代码特指两者在23标准前的情况。

demo.c & demo.cpp

/* C23 C++23 标准之前 */
void foo(void) {/* C++ 允许     *//* C   不允许   */
first:int x;/* C++ 允许     *//* C   允许     */
second:x = 1;/* C++ 不允许   *//* C   不允许   */
last:
}

尝试编译测试:

测试环境

当然笔者这里的gcc本身就不支持23标准。

$ gcc --versiongcc (x86_64-posix-seh-rev3, Built by MinGW-W64 project) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

C语言

gcc -pedantic -ansi -std=c17 -c demo.c 
demo.c: In function 'foo':
demo.c:6:5: warning: a label can only be part of a statement and a declaration is not a statement [-Wpedantic]6 |     int x;|     ^~~
demo.c:15:1: warning: label at end of compound statement [-Wpedantic]15 | last:| ^~~

C++

g++ -pedantic -ansi -std=c++20 -c demo.cpp
demo.cpp: In function 'void foo()':
demo.cpp:16:1: error: expected primary-expression before '}' token16 | }| ^

🏷️23标准后

没啥可说的,就是上面的情况在 C23/C++23 后都允许。

🏷️原因

摘自P2324R2

In C declarations and statements are separate production rules which can both appear as block-items inside compound statements.
The simplest change for C was to also allow labels as independent block-items in addition to statements and declarations.
This change then also allowed placing labels at the end of a compound statement which was seen as useful feature.


在C语言中,声明和语句是独立的生成规则,它们都可以作为复合语句中的块项出现。

对于C来说,最简单的改变是除了语句和声明之外,还允许标签作为独立的块项。

这个变化还允许在复合语句的末尾放置标签,这被认为是一个有用的特性。

In C++ declarations are statements and compound statements can only have statements as block-items.
Thus, labels can already be attached to all statements, i.e. including declarations, but can not be placed at the end of compound statements.
Another difference is that in C++ (but not in C) it is possible to use declarations as sub-statements of a control statements.
The later seems to be an unintended side effect of making declarations be statements and now requires a rewrite rule to place this declaration into a new scope.


在c++中,声明是语句,复合语句只能有语句作为块项。

因此,标签可以附加到所有语句,即包括声明,但不能放在复合语句的末尾。

另一个区别是,在c++(而不是C)中,可以将声明用作控制语句的子语句。

后者似乎是使声明成为语句的意外副作用,现在需要重写规则将该声明放入新的作用域。

🔖未兼容

来看另一个例子。

该例子在C++中式可行的,但在C语言中,即使到了C23还是不可行。

因此对于该情况,还是要添加大括号构成块级作用域规范些。

void bar(void) {/*** C++ 可行* C   不可行 (C23 仍不可行)*/if (1)
here:int x;
}

🔖END

上文代码的在线示例:https://godbolt.org/z/6MEdTheG9

🌟关注我

关注我,学习更多C/C++,算法,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com