#pragma message 官方文档翻译

本文介绍了一种在编译时显示信息的实用方法,利用messagepragma可以在不中断编译流程的情况下,输出字符串字面量至标准输出。此技术常用于在编译期间展示各类信息,如文件名、修改时间等。

一 作用

Sends a string literal to the standard output without terminating the compilation.

在不终止编译的情况下将字符串字面量发送到标准输出

二 语法

#pragma message( message-string )

三 备注

A typical use of the message pragma is to display informational messages at compile time.
The message-string parameter can be a macro that expands to a string literal, and you can concatenate such macros with string literals in any combination.
If you use a predefined macro in the message pragma, the macro should return a string. Otherwise, you'll have to convert the output of the macro to a string.
The following code fragment uses the message pragma to display messages during compilation:

翻译:message pragma的一个典型应用是在编译时显示信息消息。
message-string参数可以是一个宏扩展为一个字符串字面量,你可以以任何形式组合宏和字符串字面量。
如果在message pragma中预定义宏,该宏必须返回一个字符串,否则你必须将宏的输出转换为字符串。以下片段使用message pragma在编译过程中显示消息。

// pragma_directives_message1.cpp
// compile with: /LD
#if _M_IX86 >= 500
#pragma message("_M_IX86 >= 500")
#endif

#pragma message("")

#pragma message( "Compiling " __FILE__ )
#pragma message( "Last modified on " __TIMESTAMP__ )

#pragma message("")

// with line number
#define STRING2(x) #x
#define STRING(x) STRING2(x)

#pragma message (__FILE__ "[" STRING(__LINE__) "]: test")

#pragma message("")

四 原文

官方文档

跟上面一样/* * @copyright: copyright (c) 2025 Chengdu TP-Link Technologies Co.Ltd. * @fileName: server.h * @description: function declaration file of server.c * @Author: Wang Zhiheng * @email: wangzhiheng@tp-link.com.hk * @version: 1.0.0 * @Date: 2025-08-07 * @history: \arg 1.0.0, 25Aug07, Wang Zhiheng, Create the file */ #pragma once #ifndef __SERVER_H__ #define __SERVER_H__ /**************************************************************************************************/ /* INCLUDE FILES */ /**************************************************************************************************/ #include <arpa/inet.h> #include <sys/epoll.h> #include <pthread.h> #include <stdio.h> #include <errno.h> #include <unistd.h> #include <strings.h> #include <string.h> #include <sys/stat.h> #include <sys/sendfile.h> #include <dirent.h> #include <stdlib.h> #include <pthread.h> #include <ctype.h> #include <fcntl.h> #include <math.h> /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ /* 错误处理 */ #define handle_error(cmd, result) \ if (result < 0) \ { \ perror(cmd); \ return -1; \ } /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* VARIABLES */ /**************************************************************************************************/ /**************************************************************************************************/ /* FUNCTIONS */ /**************************************************************************************************/ /* 新建一个用于TCP监听的socket文件描述符,并返回 */ int init_listen_fd(unsigned short port); /* 启动threads */ int threads_run(int listen_fd); /* 接收http请求, cfd表示连接socket, epfd表示epoll树 */ void* recv_http_request(void* arg); /* 解析HTTP请求并分类处理 */ int parse_request(const char *message, int *conn_fd); /* 处理Get请求 */ int handle_get_request(int *conn_fd, const char *path); /* 处理Post请求 */ int handle_post_request(int *conn_fd, const char *path, const char *message); /* 处理表单信息 */ void process_contact_form(int conn_fd, const char *body); /* 返回错误信息 */ void send_error_response(int conn_fd, int code, const char *msg); /* 获取Content-Type字段 */ const char* get_mime_type(const char* filename); /* url解码 */ char *url_decode(const char *src); /* 发送HTTP响应 */ void send_http_response(int sockfd, const char* file_path); #endif /* __SERVER_H__ */
08-16
你遇到的警告: ```c warning: junk at end of '#pragma message' [-Wpragmas] #pragma message "MBEDTLS_VERSION_NUMBER=" STR(MBEDTLS_VERSION_NUMBER) ``` 以及输出结果: ``` #pragma message: MBEDTLS_VERSION_NUMBER= ``` 👉 **说明你的宏拼接没有生效,`STR(MBEDTLS_VERSION_NUMBER)` 没有被展开成实际版本数字。** --- ## ❌ 问题原因:`#pragma message` 不支持宏展开 这是关键点! ### ✅ `#pragma message` 的限制: - 它是编译器预处理指令,**只接受字符串字面量** - **不会对其中的宏进行展开**(即使你用了 `STR()` 这种技巧) - 所以 `STR(MBEDTLS_VERSION_NUMBER)` 被当作普通文本处理了 - 最终变成:`"MBEDTLS_VERSION_NUMBER=" STR(...)` → 编译器看不懂后面部分 → 报 “junk at end” 这就是为什么你会看到: ``` #pragma message: MBEDTLS_VERSION_NUMBER= ``` → 后面的内容被丢弃了。 --- ## ✅ 正确做法:使用 `_Pragma` + 宏展开机制 要让宏在 `#pragma message` 中正确展开,必须使用 C99 的 `_Pragma` 操作符,并配合多层宏展开。 ### ✅ 推荐解决方案:定义一个可展开的日志宏 ```c // 在 tpsocket_parser.c 或头文件中添加: #define STR(x) #x #define TOSTR(x) STR(x) // 使用 _Pragma 展开宏 #define PRAGMA_MSG(msg) _Pragma(TOSTR(message msg)) // 示例:打印 Mbed TLS 版本号 PRAGMA_MSG("MBEDTLS_VERSION_NUMBER=" TOSTR(MBEDTLS_VERSION_NUMBER)) ``` ### 🔍 解释每一步: | 行 | 作用 | |----|------| | `#define STR(x) #x` | 将宏参数转为字符串(但不展开) | | `#define TOSTR(x) STR(x)` | 强制先展开 `x`,再转为字符串(关键!) | | `TOSTR(MBEDTLS_VERSION_NUMBER)` | 假设值为 `0x02180000`,会被展开为 `"0x02180000"` | | `_Pragma(...)` | 是表达式形式的 pragma,支持宏展开 | | `message "..."` | 构造最终的消息字符串 | --- ### ✅ 实际效果 假设你的 Mbed TLS 版本是 `2.24.0`,即: ```c #define MBEDTLS_VERSION_NUMBER 0x02180000 ``` 那么这行: ```c PRAGMA_MSG("MBEDTLS_VERSION_NUMBER=" TOSTR(MBEDTLS_VERSION_NUMBER)) ``` 会被预处理器展开为: ```c _Pragma("message \"MBEDTLS_VERSION_NUMBER=0x02180000\"") ``` ✅ 编译时就会显示: ``` note: #pragma message: MBEDTLS_VERSION_NUMBER=0x02180000 ``` ✔️ 成功打印出真实版本号,且无警告! --- ## 🛠️ 完整示例代码 ```c #include "mbedtls/version.h" // 支持宏展开的 pragma message #define STR(x) #x #define TOSTR(x) STR(x) #define PRAGMA_MSG(msg) _Pragma(TOSTR(message msg)) // 打印版本信息 PRAGMA_MSG("MBEDTLS_VERSION_NUMBER=" TOSTR(MBEDTLS_VERSION_NUMBER)) // 可以继续加其他提示 #if MBEDTLS_VERSION_NUMBER < 0x02070000 PRAGMA_MSG("Using old Mbed TLS API (< 2.7.0)") #else PRAGMA_MSG("Using new Mbed TLS API (>= 2.7.0)") #endif void some_function(void) { // ... } ``` --- ## ⚠️ 注意事项 | 项目 | 说明 | |------|------| | `_Pragma` 是 C99 标准 | 所有现代编译器(GCC、Clang、MSVC)都支持 | | `#pragma message` 不跨平台 | 但用于调试打印没问题 | | 不要用于发布构建 | 建议用 `#ifdef DEBUG` 包裹 | | MSVC 兼容性 | MSVC 使用 `#pragma message(...)`,但 `_Pragma("message ...")` 在 Clang/GCC 上更灵活 | --- ## ✅ 更进一步:自动判断是否启用新 API 你可以用这个技巧做条件提示: ```c #if MBEDTLS_VERSION_NUMBER < 0x02070000 PRAGMA_MSG("WARNING: Using deprecated mbedtls_md5_starts (no _ret)") #else PRAGMA_MSG("INFO: Using modern mbedtls_md5_starts_ret") #endif ``` 帮助你在多人协作或迁移过程中快速识别版本差异。 --- ## ✅ 总结 | 方法 | 是否可行 | 说明 | |------|----------|------| | `#pragma message "xxx" STR(MBEDTLS_VERSION_NUMBER)` | ❌ | 宏不会展开,报“junk at end” | | `_Pragma("message \"...\"")` + `TOSTR()` | ✅ | 正确方式,支持宏展开 | | 直接写死版本号 | ✅ 但不推荐 | 失去动态性 | | 使用 `#warning` | ✅ | 但会中断编译(太强) | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值