首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >GCC和Clang printf格式检查不适用于模板函数中的解密类型

GCC和Clang printf格式检查不适用于模板函数中的解密类型
EN

Stack Overflow用户
提问于 2020-12-21 18:12:47
回答 1查看 514关注 0票数 1

这段代码即使使用-Wall -Werror也可以编译,但是它不应该:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <cstdio>

template <typename T>
void f()
{
    decltype(printf("%u", 1.0))* p = nullptr; // format does not match args
    (void)p;
}

void g()
{
    f<int>();
}

如果f()不是一个模板,GCC和Clang拒绝编译它,正如我所期望和希望的那样。但是正如上面所写的,GCC和Clang在没有任何警告的情况下编译了它。

GCC树干确实拒绝编译它,不像所有发布的版本。MSVC 19也是,但我不能用它。

,我的问题是:当格式与其论点不匹配时,您能对代码进行一些修改,使其至少在GCC 8.2中失败吗?如果它也适用于最近的Clang,那么加分也可以。

实际上,我不能用与printf()相同的签名调用printf(),甚至不能调用我自己的函数,因为我的实际代码中的一些参数来自对调用代价高昂的函数的调用。我希望能够确认printf()或类似的函数可以接受我的参数,而不实际调用任何这样的函数。

使用意外编译的模板演示:https://godbolt.org/z/rWxYob

没有正确拒绝编译的模板的演示:https://godbolt.org/z/xb6GYo

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-22 23:57:01

你可以试试:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename T>
void f()
{
    if (false) { printf("%u", 1.0); } // format does not match args
}

您可能需要一些附加的实用程序来对状态进行无声警告,计算结果总是错误的,或者是无法到达的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65402444

复制
相关文章
GCC、Clang和LLVM
GCC(GNU Compiler Collection,GNU编译器套装),是一套由 GNU 开发的编程语言编译器。
动动我试试
2020/03/12
1.1K0
scanf和printf函数的格式控制
scanf函数 %[*][数据宽度][长度]类型 其中[]中的是选填 [*]表示该输入项,读入后不赋值给变量。 例如: scanf("%d %*d %d",&a,&b); 输入1 2 3后 1赋值给a; 2被读取后,但不进行赋值; 3赋值给b; [数据宽度]指定获取的数据长度 例如: scanf("%3d%3d",&a,&b); 输入456789 第一个%3d获取输入的456789的截取前三位,后面的%3d就获取后面的三位。 456赋值给a; 789赋值给b; 长度(l或h) 读入长整型、双精度型或短整型数
布衣者
2021/09/07
6690
linux下Clang和gcc的区别
出错提示更友 好,比如 clang 在编译过程可以直接指出相对简单的出错位置以及它 “ 认为 ” 正确的方式 。
Linux阅码场
2019/06/21
5.5K0
新版GCC和LLVM+Clang终于Release啦
可能是疫情的原因,GCC好久没发布啦。最近总于又Release了,还是大版本。并且三大编译器对C++20的支持也都七七八八了。所以特意立贴庆祝一下,顺带更新一波构建脚本把这两年的一些改动列举一下。
owent
2023/03/06
7730
编译器介绍 - LLVM、GCC、Clang
虽然是叫这个名字,但是和虚拟机没什么关系,这不是一个缩写,就是这个项目的全名。是伊利诺伊大学为了提供一个现代的、基于 SSA(静态单一赋值) 的、可以动态、静态编译任何编程语言的编译方案而开展的研究项目,核心是个编译器工具集。
饶文津
2021/09/10
1.9K0
GCC 7和LLVM+Clang+libc++abi 4.0的构建脚本
之前的版本发完,有空来更新一下之前的gcc和llvm+clang工具链的编译脚本了。其实GCC 7是才release没多久但是llvm 4.0发布其实有一段时间了。
owent
2018/08/01
9690
print和println和printf的区别_print输出格式
println–与print唯一的区别是println换行输出。 printf–函数,把文字格式化以后输出,直接调用系统调用进行IO的,他是非缓冲的。 如: name=”hunte”; age=25; printf(“my name is %s, age %d”, name, age); sprintf–跟printf相似,但不打印,而是返回格式化后的文字,其他的与printf一样。 如: char sql[256]; sprintf(sql,”select * from table where no = ‘%s'”,bankno); 它的功能只是把””里面的语句赋给了变量sql。
全栈程序员站长
2022/11/09
2K0
printf格式控制符[备忘]
(1)输出格式控制综述:     printf的格式控制的完整格式:%  -  0  m.n  l或h     ①%:格式说明的起始符号,不可缺少。     ②-: 有-表示左对齐输出,如省略表示右对齐输出。     ③0:有0表示指定空位填0,如省略表示指定空位不填。     ④m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度,用于说明输出的实型数的小数位数。未指定n时,隐含的精度为n=6位。     ⑤l或h:l对整型指long型,对实型指double型。           h用于将整型的格式字符修正为short型。 (2)输出项数据类型控制综述: ①d格式:用来输出十进制整数。有以下几种用法:    %d:按整型数据的实际长度输出。 %md:m为指定的输出字段的宽度。如果数据的位数小于m,则左端补以空格,若   大于m,则按实际位数输出。    %ld:输出长整型数据。 ②o格式:以无符号八进制形式输出整数。对长整型可以用"%lo"格式输出。同样也可以指定字段宽度用“%mo”格式输出。 ③x格式:以无符号十六进制形式输出整数。对长整型可以用"%lx"格式输出。同样也可以指定字段宽度用"%mx"格式输出。 ④u格式:以无符号十进制形式输出整数。对长整型可以用"%lu"格式输出。同样也可以指定字段宽度用“%mu”格式输出。 ⑤c格式:输出一个字符。 ⑥s格式:用来输出一个串。有几中用法 %s:例如:printf("%s", "CHINA")输出"CHINA"字符串(不包括双引号)。 %ms:输出的字符串占m列,如字符串本身长度大于m,则突破m的限制,将字符 串全部输出。若串长小于m,则左 补空格。 %-ms:如果串长小于m,则在m列范围内,字符串向左靠,右补空格。 %m.ns:输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的 右侧,左补空格。 %-m.ns:其中m、n含义同上,n个字符输出在m列范围的左侧,右补空格。如果 n>m,则自动取n值,即保证n个字符正常输出。 ⑦f格式:用来输出实数(包括单、双精度),以小数形式输出。有以下几种用法: %f:不指定宽度,整数部分全部输出并输出6位小数。 %m.nf:输出共占m列,其中有n位小数,如数值宽度小于m左端补空格。 %-m.nf:输出共占n列,其中有n位小数,如数值宽度小于m右端补空格。 ⑧e格式:以指数形式输出实数。可用以下形式: %e:数字部分(又称尾数)输出6位小数,指数部分占5位或4位。 %m.ne和%-m.ne:m、n和”-”字符含义与前相同。此处n指数据的数字部分的小数 位数,m表示整个输出数据所占的宽度。 ⑨g格式:自动选f格式或e格式中较短的一种输出,且不输出无意义的零。 (3)三类特殊情况 ①如果想输出字符"%",则应该在“格式控制”字符串中用连续两个%表示,如: printf("%f%%", 1.0/3); 输出0.333333%。 对于单精度数,使用%f格式符输出时,仅前7位是有效数字,小数6位. 对于双精度数,使用%lf格式符输出时,前16位是有效数字,小数6位. ②对于m.n的格式还可以用如下方法表示 char ch[20]; printf("%*.*s/n",m,n,ch); 前边的*定义的是总的宽度,后边的定义的是输出的个数。分别对应外面的参数m和n 。 这种方法的好处是可以在语句之外对参数m和n赋值,从而控制输出格式。 ③输出格式 %n 可以将所输出字符串的长度值赋绐一个变量, 见下例: int slen; printf("hello world%n", &slen); 执行后变量slen被赋值为11。
王亚昌
2018/08/03
1.6K0
再议printf函数
System.out.printf()是在JDK1.5版开始引入的方法,即在JDK1.5以后的版本才可以使用此函数,printf 方法有 printf(Stringformat, Object ... args) 和 printf(Locale l, String format, Object... args) 两种重载方式。其实学过C语言的小伙伴应该会觉得很亲切,就是控制输出的格式。 目前printf支持以下格式:           %c        单个字符           %d        
老九君
2022/03/15
7170
C语言的printf输出格式
1、控制小数点后有多少位:printf(“%.10lf\n”,f_a); //将浮点数f_a输出时,输出其小数点后10位,默认是输出小数点后6位。
全栈程序员站长
2022/09/15
2.7K0
C++模板取函数参数类型和返回值类型的方法
static_assert(is_same_v<decltype(f), int(int, short, float)>);
用户7886150
2021/02/03
4.2K0
JavaScript中的类型检查有点麻烦
JS 的动态类型有好有坏。好的一面,不必指明变量的类型。不好的是,咱们永远无法确定变量的类型。
前端小智@大迁世界
2022/06/15
1.4K0
JavaScript中的类型检查有点麻烦
C++最佳实践 | 1. 工具
本文档旨在收集对C++最佳实践所进行的协作性讨论,是《Effective C++》(Meyers) 和《C++ Coding Standards》(Alexandrescu, Sutter) 等书籍的补充。在讨论如何确保整体代码质量的同时,补充了一些没有讨论到的较低级别的细节,并提供了具体的风格建议。
C语言与CPP编程
2022/10/31
3.4K0
Go 中的格式化字符串`fmt.Sprintf()` 和 `fmt.Printf()`
在 Go 中,可以使用 fmt.Sprintf() 和 fmt.Printf() 函数来格式化字符串,这两个函数类似于 C 语言中的 scanf 和 printf 函数。
除除
2023/06/17
5950
Go 中的格式化字符串`fmt.Sprintf()` 和 `fmt.Printf()`
[C] printf函数用法详解
| 符号 |意义 | | ------| | %c | 字符| |%a(%A)|浮点数、十六进制数字和p-(P-)记数法(C99)| |%d|有符号十进制数| | %e(%E) | 浮点数指数输出[e-(E-)记数法| | %g(%G) | 浮点数不显无意义的零"0"| | %i | 有符号十进制整数(与%d相| | %u | 无符号十进制整数| | %o | 八进数| | %x(%X) |十六进制整数0f(0F) | | %p | 指针| | %s | 字符串| | %% | 输出"%"|
轻舞飞扬SR
2021/02/24
4390
printf函数的求值顺序问题
printf的参数,函数printf从左往右读取,然后将先读取放到栈底,最后读取的放在栈顶,处理时候是从栈顶开始的,所有从右边开始处理的。
ccf19881030
2019/04/29
1K0
printf函数的返回值!
这样的题目第一眼看上去有一点懵,其实它考的就是printf函数的返回值,及输出字符的个数。 输出结果
lexingsen
2022/02/24
3.3K0
Python小姿势 - # Python中的类型检查
```python 声明一个整型变量 num: int 声明一个字符串变量 name: str
不吃西红柿
2023/05/04
6660
关于c++中printf语句输出string类型乱码
运行上述程序,会出现下面的结果。 这是怎么回事啊,%s对应字符串类型,应当没有错啊。 如果将输出语句改成cout,输出则会恢复正常。 printf只能输出C语言中的内置数据,string不是c语言内置数据。 更深入的来说:s这个string类型的对象并非单单只有字符串,其内还有许多用于操作的函数,于是&s并非字符串“helloworld”的首地址,而是s这个对象的首地址。 所以要做如下操作: string s = “helloworld”; printf("%s" , s.c_str());//string中c_str()成员方法返回当前字符串的首字符地址。 所以方便点还是cout吧。
用户7886150
2021/02/13
1.9K0
点击加载更多

相似问题

具有可选格式字符串参数和GCC格式类型检查的类Printf函数

10

朋友缩写模板函数- clang和gcc不同

15

删除的模板函数适用于gcc,而不是clang。

12

通过引用传递数组作为模板参数适用于gcc和clang,但不适用msvc。

15

函数指针类型擦除不适用于GCC。

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文