在 C 预处理器中,“#”字符是否必须位于行的开头? [复制]

2024-04-02

我已经用 C 语言编程有一段时间了。在此期间,我了解到将预处理器指令之前的“#”字符放在第一列是一种常见的约定。

Example:

 #include <stdio.h>

 int main(void) {
 #ifdef MACRO1
 #ifdef MACRO2
      puts("defined(MACRO1) && defined(MACRO2)");
 #else
      puts("defined(MACRO1)");
 #endif
 #else
      puts("!defined(MACRO1)");
 #endif
      return 0;
 }

当人们缩进预处理器指令时,他们通常会这样做:

 #include <stdio.h>

 int main(void) {
 #ifdef MACRO1
 # ifdef MACRO2
     puts("defined(MACRO1) && defined(MACRO2)");
 # else
     puts("defined(MACRO1)");
 # endif
 #else
     puts("!defined(MACRO1)");
 #endif
     return 0;
 }

我认为我从未见过有人这样格式化它:

 #include <stdio.h>

 int main(void) {
 #ifdef MACRO1
  #ifdef MACRO2
     puts("defined(MACRO1) && defined(MACRO2)");
  #else
     puts("defined(MACRO1)");
  #endif
 #else
     puts("!defined(MACRO1)");
 #endif
     return 0;
 }

我的问题是 C 语言标准是否要求#- 字符应位于第一列。

那么上面的第三种选择合法吗?

如果以上所有情况都是合法的,那么我想知道这是否合法。

 #include <stdio.h>

 int main(void) {
 #ifdef MACRO
     puts("defined(MACRO)");
 /* Now there are other characters before the `#` */ #endif
     return 0;
 }

这里是#endif不再位于该行的“开始”,因为中间还有其他非空白字符。

最后一个例子看起来很奇怪的是Vim文本编辑器不突出显示#endif评论之后。

我给出的所有这些示例都使用编译时没有任何警告gcc-Wall -pedantic标志已打开(包括最后一个之前有评论的标志)#endif).

请注意,我只是对语法感到好奇。我总是把#-当我编程时,第一列的字符与其他人一样。我永远不会写这样的东西++i; #endif在严肃的项目中。


在一些标准之前的 C 预处理器中(指 1989 年之前),预处理器仅识别#在该行的开头。

由于 C89/C90 标准要求预处理器识别#作为行中的第一个非空白字符(C99 和 C11 标准也是如此),现在缩进指令是完全合法的,而且在这整个千年里,即使是可移植代码也这样做是很实用的。

在 ISO/IEC 9899:2011(C11 标准)中,第 6.10 节预处理指令表示:

A 预处理指令由一系列满足以下条件的预处理标记组成 以下约束:序列中的第一个标记是#预处理标记(在 翻译阶段 4) 的开始是源文件中的第一个字符(可选 在不包含换行符的空白之后)或在空白之后 至少包含一个换行符。

翻译阶段在第 5.1.1.2 节翻译阶段中定义。

  1. 源文件被分解为预处理标记 7) 和序列 空白字符(包括注释)。源文件不得以 部分预处理标记或部分注释中。每个评论都被替换为 一个空格字符。保留换行符。是否每个非空 除换行符之外的空白字符序列被保留或替换为 一个空格字符是实现定义的。

  2. 执行预处理指令,扩展宏调用,并且 _Pragma 一元运算符表达式被执行。如果一个字符序列 匹配由 token 生成的通用字符名称的语法 串联 (6.10.3.3),行为未定义。 A#include预处理 指令导致指定的头文件或源文件从第 1 阶段开始处理 递归地完成第 4 阶段。然后删除所有预处理指令。

有时,您会发现源自 20 世纪 80 年代的编码标准仍然规定 '#在行的开头'。

我通常不会缩进预处理器指令,但这样做是合法的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C 预处理器中,“#”字符是否必须位于行的开头? [复制] 的相关文章

  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • 使用 glFrustum 进行离轴投影

    我正在尝试使用 OpenGL 对场景进行离轴投影 并且我阅读了该文档罗伯特 库伊马的离轴投影 http csc lsu edu kooima pdfs gen perspective pdf现在对实际需要做什么有了更好的了解 但仍然有一些部
  • Java PaintComponent 告诉是否再次调用

    谷歌搜索了几天 我不知道如何判断在处理paintComponent时是否调用了paintComponent 这个过程漫长而复杂 如果我有第二个 或第三个 绘制请求 我想中止当前的绘制过程并重新开始最近的请求 你不能 打电话给paintCom
  • TensorFlow 2.0 中不再提供投影变换,我该怎么办?

    我的团队正在切换到 TensorFlow 2 0 我正在研究数据增强管道 TensorFlow 1 X 有tf contrib image transform允许投影变换 TensorFlow 中没有变换函数tf image它肯定没有tf
  • AzureDev Ops CI 构建未更新版本 (VersionPrefix)

    我有一个 Azure DevOps 管道 其中包含本地 nuget 包到本地工件存储库 然后推送到 nuget org 但是它不会更新版本并保持在1 0 0 build ver 在本地 azure DevOps 项目工件中 同时版本卡在包的
  • 如何根据控件的属性(Top/Tabstop)设置WPF动画BeginTime

    我有一个 WPF 应用程序 它在垂直堆栈面板中具有一系列按钮 类似于 DVR 菜单的外观 我想出了如何制作一个动画 当每个新的菜单页面加载时 按钮 控件全部 unfade fall deblur 无论什么 都存在 这很好 但有点太统一了 我
  • 使用非常量表达式作为模板参数

    这是后续如何获取可变参数模板类中函数指针的参数类型 https stackoverflow com questions 9065081 how do i get the argument types of a function pointe
  • 生成器完成后调用自耕农生成器

    我希望在第一个生成器完成安装后调用另一个 yeoman 生成器 这将基于我对其中一个提示给出的答案 我尝试在最后调用它 end function this installDependencies callback function if t
  • JAXB - 将 SOAP 映射到 Java 类

    我需要帮助将我的 Soap Envelope 映射到 java 类 我的目的是将结果操纵到数据库 我在获取 SOAP 信封或使用 DB 方面没有任何问题 我的问题完全在于 JABX 以及根据我的 SOAP 信封映射我的类 这是我的肥皂
  • 登录时传递cookie

    我想集成 python Selenium 和 Requests 模块以在网站上进行身份验证 我正在使用以下代码 import requests from selenium import webdriver driver webdriver
  • 如何在 SQLite 查询中使用正则表达式?

    我想在 sqlite 中使用正则表达式 但我不知道如何 我的表有一列包含如下字符串 3 12 13 14 19 28 32 现在 如果我输入 where x LIKE 3 我还会得到包含 13 或 32 等值的行 但我只想获取该字符串中恰好
  • 以编程方式在 UITableViewCell 中呈现带有按钮的视图控制器 (Swift)

    I am trying to make it where when a user clicks on a table view cell in my table view it takes them to a new view contro
  • Outlook 插件 - 获取当前选定的日历日期

    当右键单击日历并运行功能区操作时 是否可以像获取当前邮件项或约会项一样获取选定的日历日期 功能区 XML
  • 是否可以将组件作为 props 传递并在 Vue 的子组件中使用它?

    在 Vue 2 0 应用程序中 假设我们有组件 A B 和 C A声明 注册并使用B 是否可以将C从A传递到B 像这样的事情
  • 如何取消numpy seed()的效果?

    我想在程序的第一部分使用 np random seed 并在第二部分取消它 再次 在我的 python 文件的第一部分中 我希望在每次执行时生成相同的随机数 在第二部分中 我希望在每次执行时生成不同的随机数 在第一部分中 使用常量初始化种子
  • Exchange Web 服务附件加载缓慢

    我正在编写一些代码来下载和处理电子邮件的附件 然后处理它们 该代码在某些情况下可以按要求工作 但仍然存在一些重大问题 每当代码将附件加载到本地磁盘上的文件中时 都会花费很长的时间 并且经常会由于下载缓慢而超时 并出现以下异常 A first
  • 意外查询成功

    SELECT COUNT FROM rps2 workflow WHERE workflow added gt TO DATE 01 09 2011 dd mm yyyy AND workflow finished lt TO DATE w
  • 如何将 system.data.SQLite.dll 的引用添加到 Windows Phone 7

    我是 Windows Phone 7 的新手 请帮我解决这个问题 我想在Windows Phone 7中添加SQLite数据库 我下载了system data SQLite dll 来自sourceforge www sqlite org
  • 蓝鸟承诺解析(数据)在客户端代码中未定义

    希亚斯 我有一个简单的应用程序 客户端期望得到一个承诺作为结果 但是在调用resolve 方法时 承诺不断返回未定义的结果 客户端代码 UsersRepo findOneAsync id id then function err resul
  • 为函数想出好的名字时遇到困难

    因此 我经常难以用简洁的名称描述函数 对于重用的功能来说 这通常不是问题 但通常需要将大型流程分解为子功能 这些通常会得到奇怪的名字 例如connectionsToAccessLines or handleWallVisionSplit或类
  • 在 C 预处理器中,“#”字符是否必须位于行的开头? [复制]

    这个问题在这里已经有答案了 我已经用 C 语言编程有一段时间了 在此期间 我了解到将预处理器指令之前的 字符放在第一列是一种常见的约定 Example include