我正在研究Linux机器.是否有任何系统命令可以找到我正在使用的C编译器后面的标准?
我想建议使用的<inttypes.h>做给别人printf用混合32/64位版本.我尝试了谷歌的介绍或教程页面,其中包含一些示例和使用指南,但我找不到一个.
有人可以推荐一个介绍或教程<inttypes.h>吗?
我想在项目中定义一个内联函数,用c99编译.我该怎么做?当我在头文件中声明该函数并在.c文件中提供详细信息时,其他文件无法识别该定义.当我将显式函数放在头文件中时,我遇到了一个问题,因为使用它的所有.o文件都有定义的副本,因此链接器给我一个"多重定义"错误.
我想要做的是:
header.h
inline void func()
{
do things...
}
lib1.c
#include "header.h"
...
lib2.c
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
使用lib1.o和lib2.o的实用程序
在我的程序中,我有一个功能,可以添加一个简单的向量c[0:15] = a[0:15] + b[0:15].功能原型是:
void vecadd(float * restrict a, float * restrict b, float * restrict c);
Run Code Online (Sandbox Code Playgroud)
在我们的32位嵌入式架构中,有一个加载/存储双字加载/存储选项,如:
r16 = 0x4000 ;
strd r0,[r16] ; stores r0 in [0x4000] and r1 in [0x4004]
Run Code Online (Sandbox Code Playgroud)
GCC优化器识别循环的向量性质并生成代码的两个分支 - 一个用于3个数组是双字对齐的情况(因此它使用双重加载/存储指令)而另一个用于数组的情况是字对齐的(它使用单个加载/存储选项).
问题是地址对齐检查相对于加法部分是昂贵的,我想通过暗示编译器a,b和c始终是8对齐来消除它.是否有一个修饰符添加到指针声明以告诉编译器?
用于调用此函数的数组具有aligned(8)属性,但它不会反映在函数代码本身中.是否可以将此属性添加到函数参数?
此代码为-O1和-O2提供不同的结果:
/*
Example of a clang optimization bug.
Mark Adler, August 8, 2015.
Using -O0 or -O1 takes a little while and gives the correct result:
47 bits set (4294967296 loops)
Using -O2 or -O3 optimizes out the loop, returning immediately with:
0 bits set (4294967296 loops)
Of course, there weren't really that many loops. The number of loops was
calculated, correctly, by the compiler when optimizing. But it got the
number of bits set wrong.
This is with:
Apple …Run Code Online (Sandbox Code Playgroud) 我一直在寻找一种可移植的方法来强制CMake启用编译器的C99功能,以避免出现以下gcc错误:
error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int s = 1; s <= in_para->StepNumber; s++){
^
Run Code Online (Sandbox Code Playgroud)
我也不想检查哪个编译器并附加如下内容:
set(CMAKE_C_FLAGS "-std=c99") # that would be bad
Run Code Online (Sandbox Code Playgroud)
所以我发现这篇文章:在CMake中启用C99以及相关的功能请求:0012300:CMake没有跨平台的方式来请求C99.在这个Mantis bug中,我了解了target_compiler_features之后我发现了这些SOF答案:如何在CMake中激活C++ 11?以及如何使用CMake检测编译器的C++ 11支持.
所以我的问题是:这target_compiler_features将提供一种需要C功能和C++功能的方法吗?现在最简单的方法是什么 - 我目前正在使用CMake 2.8.12.2.这target_compiler_features不是CMake的最新发行版本(3.0.0).你知道什么时候被释放吗?
刚刚在ISO/IEC9899中找到了一些东西我偶然发现了这个:
6.7.6类型名称
[...]
语义
2在几种情况下,有必要指定一种类型.这是使用类型名称完成的,类型名称在语法上是函数的声明或省略标识符的该类型的对象.128)3示例构造
(a) int
(b) int *
(c) int *[3]
(d) int (*)[3]
(e) int (*)[*]
(f) int *()
(g) int (*)(void)
(h) int (*const [])(unsigned int, ...)
Run Code Online (Sandbox Code Playgroud)
name分别命名为(a)int,(b)指向int的指针,(c)指向int的三个指针的数组,(d)指向三个int的数组的指针,(e)指向未指定数字的可变长度数组的指针oft,(f)没有参数规范的函数返回指向int的指针,(g)指向函数的指针,没有返回int的参数,以及(h)指向函数的未指定数量的常量指针的数组,每个指针都有一个参数具有unsigned int类型和未指定数量的其他参数,返回int.
让我最困惑的是:
(e)指向未指定数量的整数的可变长度数组的指针
我可以或多或少地了解其他人.但是指向未指定数量的'整数'的VLA的指针有什么用?
甚至还需要编译器来支持语法
int foo[*];
Run Code Online (Sandbox Code Playgroud)
?
编辑澄清
本课题主要针对"是否有必要为编译器提供支持?".虽然这篇文章ANSI-C语法 - 像[*] et alii这样的数组声明明显提高了我的知识.仍然没有答案:为什么编译器需要知道原型的参数是否是包含未知大小的地址.只是简单地做int foo[]或者它将是未指定的大小?
那么真的有必要得到支持吗?如果不是这样,那为什么标准甚至会实现这种语义呢?
我restrict对此有一个大致的了解,但我希望澄清一些细节.我有一个函数从一个缓冲区读取一个以null结尾的字符串,并在另一个缓冲区中写出一个URL编码的版本.该函数具有此签名(当前没有restrict):
char const *StringUrlEncode(char const *unencoded,
char *encoded,
char *encodedEnd);
Run Code Online (Sandbox Code Playgroud)
unencoded是我的以null结尾的源字符串.目标缓冲区由encoded和表示encodedEnd,其中encoded指向char缓冲区encodedEnd中的第一个并指向缓冲区后的第一个字符,即函数将写入char但不包括指向的位置encodedEnd- 这是您的基本begin/ end迭代器如果您熟悉C++ STL约定,请配对.
如果我添加restrict到此函数,它应该只应用于前两个参数:
char const *StringUrlEncode(char const *restrict unencoded,
char *restrict encoded,
char *encodedEnd);
Run Code Online (Sandbox Code Playgroud)
或者通过将它添加到所有三个参数中我是否有一些好处?
我可以看到制作输入和输出缓冲区restrict有助于编译器知道它们不重叠.但是由于最后一个参数,encodedEnd仅用于标记输出缓冲区的结尾,我认为这restrict对编译器没有任何帮助(虽然我认为它不会受到伤害,除了添加不必要的噪声到函数声明).
即使是一个老朋友,我担心我不再(完全)完全掌握在C中解析常量.下面的第二个1行无法编译:
int main( void ) { return (0xe +2); }
int main( void ) { return (0xe+2); }
Run Code Online (Sandbox Code Playgroud)
$ gcc -s weird.c
weird.c: In function ‘main’:
weird.c:1:28: error: invalid suffix "+2" on integer constant
int main( void ) { return (0xe+2); }
^
Run Code Online (Sandbox Code Playgroud)
根据C11标准条款6.4.4.2,编译失败的原因可能是0xe + 2被解析为十六进制浮点常量.我的问题是,是否存在在C中编写十六进制和十进制数的简单加法的约定,我不喜欢在解析时依赖于空格.
这是使用gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.9).在预处理(-E)之后停止编译显示编译失败发生在gcc而不是cpp中.