-Werror = format:编译器如何知道

 佳人蔚虹的小资心情_396 发布于 2023-02-12 14:22

我写了这个故意错误的代码

printf("%d %d", 1);

g++和编译-Werror=format.

编译器给出了令人印象深刻的警告:

error: format '%d' expects a matching 'int' argument [-Werror=format]

据我所知,编译器无法判断代码是错误的,因为格式字符串直到运行时才被解析.

我的问题:编译器是否有一个特殊的功能,可以用于printf和类似的libc函数,或者这是一个我可以用于自己的函数的功能?字符串文字?

2 个回答
  • 据我所知,编译器无法判断代码是错误的,因为格式字符串直到运行时才被解析.

    只要格式字符串是字符串文字,就可以在编译时解析它.如果不是(无论如何通常都是个坏主意),那么你可以从中得到警告-Wformat-security.

    编译器是否有一个特殊的功能,可以启动printf和类似的libc函数?

    是.

    或者这是我可以用于我自己的功能的功能?

    是的,只要你使用的格式字符串作为相同的样式printf(或其他各种标准功能,如scanfstrftime).

    void my_printf(Something, char const * format, SomethingElse, ...)
        __attribute__ ((format (printf,2,4)));
    

    表示第二个参数是一个printf样式格式字符串,格式值以第四个开头.请参阅http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html.

    2023-02-12 14:27 回答
  • 好吧,printf绝对要在运行时解析格式字符串才能完成它的工作.但是,如果它想要,编译器可能不会选择自己解析它.

    文档-Wformat说明这正是发生的事情:

    -Wformat

    -Wformat=n

    检查电话printfscanf等,以确保提供参数>适当指定的格式字符串类型,并在格式字符串指定的转换是有意义的.这包括标准的功能,以及其他由格式属性指定(见函数属性),在printf,scanf, strftimestrfmon(一个X /开启延伸,而不是在C标准)的家庭(或其他靶特异性家庭).在没有指定格式属性的情况下检查哪些函数取决于所选的标准版本,并且对没有指定属性的函数的这种检查由-ffreestanding或禁用-fno-builtin.

    根据GNU libc 2.2版支持的格式功能检查格式.这些包括所有ISO C90和C99功能,以及单Unix规范和一些BSD和GNU扩展的功能.其他库实现可能不支持所有这些功能; GCC不支持警告超出特定库限制的功能.但是,如果-Wpedantic与-Wformat一起使用,则会给出关于不在所选标准版本中的格式功能的警告(但不是针对strfmon格式的警告,因为这些格式不在C标准的任何版本中).请参阅选项控制C方言.

    更新:原来你可以在你自己的功能上使用它.迈克有详细信息.

    2023-02-12 14:27 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有