Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从数据类型推断格式说明符?_C_Types_Printf_Format Specifiers - Fatal编程技术网

C 从数据类型推断格式说明符?

C 从数据类型推断格式说明符?,c,types,printf,format-specifiers,C,Types,Printf,Format Specifiers,是否可以通过编程方式推断数据类型的格式说明符?例如,如果打印时间较长,它会自动执行以下操作: printf("Vlaue of var is <fmt_spec> ", var); 我知道后两个确实有警告,但如果抛出错误不是更好吗?因为在大多数情况下,这将是有问题的?或者我遗漏了什么,或者已经有了这样做的结构 从数据类型推断格式说明符 没有 正如melpomene所说: “格式说明符不仅仅用于类型。例如,%o和%x都采用无符号整数;%E,%f,%g全部采用双精度;%d,%i,%c全

是否可以通过编程方式推断数据类型的格式说明符?例如,如果打印时间较长,它会自动执行以下操作:

printf("Vlaue of var is <fmt_spec> ", var);
我知道后两个确实有警告,但如果抛出错误不是更好吗?因为在大多数情况下,这将是有问题的?或者我遗漏了什么,或者已经有了这样做的结构

从数据类型推断格式说明符

没有

正如melpomene所说:

“格式说明符不仅仅用于类型。例如,
%o
%x
都采用
无符号整数
%E
%f
%g
全部采用
双精度
%d
%i
%c
全部采用
整数
。这就是为什么(通常)不能从参数推断它们。”

问题是,如果存在这样一个功能,那么它会将
未初始化的int
推断为
%o
%x
,例如?等等


关于某些情况下是否应该发出警告或问题,您应该考虑铸造是如何工作的,以及何时允许某些事情是有意义的。在GCC中,您当然可以将警告视为错误:

如你所知

是否可以通过编程方式推断数据类型的格式说明符

使用
printf()
既不容易也不直接,但是

是的,通过使用
\u Generic
对一组选定的类型进行限制

这可以通过多种方式完成,并且很难与
*printf()
一起使用,但是我发现了一种类似的方法来打印数据,而不需要在本例中指定单独的格式说明符:

注意:这段代码有一个关于指针数学的编码漏洞,我已经修补过了——尽管没有发布

GPrintf("Name is ", GP(name), " is ", GP(dob), GP_eol);
关键是使用
\u Generic(parameter)
引导选择用于将类型转换为文本的代码,方法是将宏
GP(x)
展开为两部分:字符串和
x
。然后
GPrintf()
解释参数。

这类似于注释,但停留在C而不是C++中。有些编译器(GCC,Clang)为不匹配的格式和参数发出警告。但要回答你的问题:不,这真的不可能。C没有或的内置功能。您无法以标准方式在运行时获取数据类型。此外,使用GCC和Clang,您可以轻松地将特定警告转化为错误。或者将所有警告转换为错误,然后禁用特定警告的错误。因为程序员创建变量,所以程序员需要知道变量的类型,因此责任在于调用方。没有很好的编程方式来处理格式说明符。理论上这是可能的。我相信可以使用可变模板和constexpr格式的字符串扫描来完成。虽然这不是一项简单的任务,但它是可能的。如果你真的关心类型正确性,你应该使用streams。@MichaëlRoy问题是关于C的。有一个关于
\u Generic
的缺陷报告。一些解释将留待执行。例如,
size\u t
是标准类型的
typedef
,但是它使用了一个独特的转换类型说明符。@Olaf关于“
size\u t
typedef
”可以用
\u Generic
级别处理。例如,顶级使用
无符号、无符号、长、无符号长
默认值
<代码>默认值使用具有
大小的第二级通用代码。这并不总是提供
z
,但允许代码区分它是否重要。IOW可以有一个可比较的说明符。请阅读6.5.1.1p2:“…同一泛型选择中的两个泛型关联不能指定兼容的类型…”-您是否不同意别名
typedef unsigned int size\u t
无符号整数
兼容?阅读报告;还有更多的问题。它明确地将clang和gcc列为不同的实现。除此之外:对于一个不存在的问题来说,这是太多的困惑了。C是静态类型,所有类型在编译时都是已知的,打印通常使用已知类型。特殊输出需要额外注意(如链接示例所示)。寻找问题的解决方案。@Olaf I并没有在同一个泛型选择中建议
size\u t
无符号
,而是在不同的级别。简洁的例子:
\define info2(X)u Generic((X),\size\u t:“z”,\default:“?”\)\define info(X)u Generic((X),\unsigned long:“ull”,\unsigned long:“ul”,\unsigned:“u”,\default:info2(X)\)int main(){size\u t sz;put(info(sz));unsigned u;put(info(u))}
好的,这可能有效。但是如果
size\u t
是编译器的附加类型,该怎么办呢。例如,gcc定义了许多内部类型和宏以保持标题更干净(例如,
INT\u MIN
等就是这样定义的)。老实说:你真的推荐这一切吗?如果你只有一把锤子,每个问题看起来都像钉子。有些问题用锤子解决不了。如果有很多输出,像Python这样的动态语言肯定是更好的选择。
-Werror
Make all warnings into errors.

-Werror=
Make the specified warning into an error. The specifier for a warning is appended; for example -Werror=switch turns the warnings controlled by -Wswitch into errors. This switch takes a negative form, to be used to negate -Werror for specific warnings; for example -Wno-error=switch makes -Wswitch warnings not be errors, even when -Werror is in effect.

The warning message for each controllable warning includes the option that controls the warning. That option can then be used with -Werror= and -Wno-error= as described above. (Printing of the option in the warning message can be disabled using the -fno-diagnostics-show-option flag.)

Note that specifying -Werror=foo automatically implies -Wfoo. However, -Wno-error=foo does not imply anything.
GPrintf("Name is ", GP(name), " is ", GP(dob), GP_eol);