【问题标题】:Isn't there a syntax error? Should printf("one" ", two and " "%s.\n", "three" ); be valid code?没有语法错误吗?应该 printf("one" ", two and " "%s.\n", "three" );是有效的代码?
【发布时间】:2013-12-31 03:23:48
【问题描述】:

看看这段代码:

#include <stdio.h>

#define _ONE "one"
#define _TWO_AND ", two and "
int main()
{
    const char THREE[6] = "three" ;
    printf(_ONE _TWO_AND "%s.\n", THREE );
    return 0;
}

printf 实际上是:

printf("one" ", two and " "%s.\n", "three" );

输出是:

一、二、三。

gcc 在编译此代码后既不提供错误消息,也不提供警告消息。 gcc 编译器应该以这种方式工作,还是一个错误?

【问题讨论】:

  • 你的 gcc 命令是什么样子的?
  • 您显然是在假设代码是无效的 C。您为什么要这样假设?
  • 我不知道为什么由于没有发生 SSCCE 而另外两票要关闭。该代码明确展示了 OP 想要知道的是否是标准行为,并且它确实可以编译和运行。即使存在原始拼写错误,问题的意图也很明显。

标签: c gcc syntax c-preprocessor string-literals


【解决方案1】:

这是标准行为,如果我们查看C99 draft standard 部分5.1.1.2 翻译阶段 段落6 说,相邻的字符串文字会连接在一起:

连接相邻的字符串文字标记

gcc 确实有许多非标准扩展,但如果您使用-pedantic 构建,那么gcc 应该会在它执行非标准操作时警告您,您可以在文档部分Extensions to the C Language Family 中阅读更多信息。

基本原理在Rationale for International Standard—Programming Languages—C 中进行了说明,并在6.4.5 部分中说字符串文字

一个字符串可以通过使用反斜杠换行续行来跨多行,但这要求字符串的续行从下一行的第一个位置开始。为了允许更灵活的布局,并解决一些预处理问题(参见 §6.10.3),C89 委员会引入了字符串文字连接。将连续的两个字符串文字粘贴在一起,中间没有空字符,以组成一个组合字符串文字。对 C 语言的这种添加允许程序员将字符串文字扩展到物理行的末尾之外,而不必使用反斜杠换行机制,从而破坏程序的缩进方案。没有引入显式连接运算符,因为连接是词法构造而不是运行时操作。

【讨论】:

  • 优秀的答案。谢谢
  • 请注意,字符串文字连接是处理的第 6 阶段;预处理器是第 4 阶段,早在字符串连接之前。
【解决方案2】:

您没有收到任何错误,因为没有/没有任何错误。

连接两个字符串"A""B"。这是语言 C 的约定。

【讨论】:

    【解决方案3】:

    尝试gcc -E 显示预处理的源代码。你会有这样的东西:

    int main()
    {
        const char THREE[6] = "three";
        printf("one" ", two and" "%s.\n", THREE );
        return 0;
    }
    

    然后,按照@shafik-yaghmour 的正确答案进行操作

    【讨论】:

    • 您的答案应该作为对@Shafik 答案的评论发布。您提供的只是“gcc -E”评论,它没有回答发布的问题。
    猜你喜欢
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 2022-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    相关资源
    最近更新 更多