Tag: c99

在GCC或Cygwin中创建DLL?

我需要帮助将脚本(“iterator.c”)编译成DLL。 我不能使用VS2010,因为它不支持在C99标准中添加到C的function(我使用“complex.h”但VB不支持它)。 我一直在寻找替代品,但我发现的只是GCC,我不知道如何安装/使用(真的,我花了半个小时阅读文档,我甚至不懂我应该安装它,和Cygwin,我已经安装但我不知道如何使用它们。 另外,我已经安装了MinGW,但我认为它与Cygwin或多或少相同,我仍然不知道如何制作DLL。 这并不像我一直都懒惰甚至没有尝试过,只是因为这些编译器并不像我以前用过的任何东西(主要是Python IDLE和Visual Studio,它们让你很容易)。 我有点迷茫。 有人可以给我一些关于如何使用这个工具来制作我可以从另一个脚本访问的DLL的建议吗? 这非常重要。 先感谢您。

C99中“算术运算”的定义是什么?

在C99中,术语算术运算出现了16次,但我没有看到它的定义。 术语算术运算符仅在文本中出现两次(同样没有定义)但它确实出现在索引中: 算术运算符 添加剂,6.5.6,G.5.2 按位,6.5.10,6.5.11,6.5.12 递增和递减,6.5.2.4,6.5.3.1 乘法6.5.5,G.5.1 转变,6.5.7 一元,6.5.3.3 然后我们有+ – | & (二进制) ++ — * (二进制) / % << >> ~作为算术运算符,如果索引被认为是规范的! 也许我们应该将算术运算识别为算术运算符的使用。 但是F9.4.5表示sqrt()函数也是算术运算,详情请参考IEC 60559(又名IEEE754)。 因此必须有算术运算,而不仅仅是算术运算符的使用。

int main(){}(没有“void”)在ISO C中是否有效且可移植?

C标准为托管实现指定了两种main的定义forms: int main(void) { /* … */ } 和 int main(int argc, char *argv[]) { /* … */ } 它可以以与上述“等效”的方式定义(例如,您可以更改参数名称,将int替换为定义为int的typedef名称,或将char *argv[]替换为char **argv )。 它也可以“以某种其他实现定义的方式”定义 – 这意味着如果实现记录它们int main(int argc, char *argv[], char *envp)是有效的。 “在其他一些实施定义的方式”条款不在1989/1990标准中; 它是由1999标准添加的(但早期标准允许扩展,因此实现仍然允许其他forms)。 我的问题是:鉴于当前(2011)ISO C标准,是表格的定义 int main() { /* … */ } 对所有托管实现有效且可移植? (请注意,我没有解决void main或在C ++中没有使用括号的int main() 。这只是ISO C中的int main(void)和int main()之间的区别。)

将整数值转换为void *并在POSIX中再次返回是否总是安全的?

这个问题几乎与我发现的其他一些问题重复,但这个问题特别涉及POSIX,这是我在pthreads中遇到的一个非常常见的例子。 我主要关心当前的事态(即C99和POSIX.1-2008或更高版本),但任何有趣的历史信息当然也很有趣。 问题基本上归结为b是否总是采用与以下代码中的a相同的值: long int a = /* some valid value */ void *ptr = (void *)a; long int b = (long int)ptr; 我知道这通常有效,但问题是它是否是一个正确的事情(即,C99和/或POSIX标准是否保证它将起作用)。 说到C99似乎没有,我们有6.3.2.3: 5整数可以转换为任何指针类型。 除了之前指定的,结果是实现定义,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示.56) 6任何指针类型都可以转换为整数类型。 除了之前指定的,结果是实现定义。 如果结果无法以整数类型表示,则行为未定义。 结果不必在任何整数类型的值范围内。 即使使用intptr_t,标准似乎只能保证任何有效的void *都可以转换为intptr_t并再次返回,但它不能保证任何intptr_t都可以转换为void *并再次返回。 但是,POSIX标准仍然可以允许这样做。 我没有很大的愿望使用void *作为任何变量的存储空间(即使POSIX应该允许它我觉得它很难看),但我觉得我必须要问因为pthreads_create函数的常见例子使用了start_routine的参数是一个整数,它作为void *传入,并在start_routine函数中转换为int或long int。 例如, 此联机帮助页有这样的示例(请参阅完整代码的链接): //Last argument casts int to void * pthread_create(&tid[i], NULL, sleeping, (void *)SLEEP_TIME); /* … […]

使用void *键入punning而不破坏C99中的严格别名规则

我最近遇到了严格的别名规则,但是我无法理解如何使用void *来执行类型惩罚而不违反规则。 我知道这违反了规则: int x = 0xDEADBEEF; short *y = (short *)&x; *y = 42; int z = x; 而且我知道我可以安全地使用C99中的联合进行类型惩罚: union{ int x; short y; } data; data.x = 0xDEADBEEF; data.y = 42; int z = data.x; 但是如何在C99中使用void *来安全地执行类型惩罚呢? 以下是正确的: int x = 0xDEADBEEF; void * helper = (void *)&x; short *y = (short *)helper; […]

如何在C99多文件项目中声明内联函数?

我想在项目中定义一个内联函数,用c99编译。 我该怎么做? 当我在头文件中声明该函数并在.c文件中提供详细信息时,其他文件无法识别该定义。 当我将显式函数放在头文件中时,我遇到了问题,因为使用它的所有.o文件都有定义的副本,因此链接器给出了“多重定义”错误。 我想要做的是: header.h inline void func() { do things… } lib1.c #include “header.h” … lib2.c #include “header.h” 使用lib1.o和lib2.o的实用程序

C99不是GCC的默认C版本?

为什么GCC默认不编译C99? 我的意思是为什么每次编写C99代码时都需要添加–std = c99标志?

C99中那些奇怪的数组大小和是什么?

显然,以下函数原型在C99和C11中有效: void foo(int a[const *]); void bar(int a[static volatile 10]); 那些奇怪的下标符号* , static和CV限定符的目的是什么? 它们有助于区分静态类型数组和可变长度数组吗? 或者他们只是语法糖?

C99复杂支持与visual studio

我想使用C99中定义的复数,但我需要支持不支持它的编译器(MS编译器会浮现在脑海中)。 我不需要很多function,并且在没有支持的情况下在编译器上实现所需的function并不困难。 但我很难实现’类型’本身。 理想情况下,我想做的事情如下: #ifndef HAVE_CREAL double creal(complex z) { /* …. */ } #endif #ifndef HAVE_CREALF float creal(float complex z) { /* … */ } #endif 但是如果编译器无法识别’float complex’,我不确定如何做到这一点。 我实际上认为这是不可能的,但Dinkumware的C库似乎表明不是这样。 解决办法是什么 ? 我不介意使用函数/宏来对类型进行操作,但是我需要一种方法来为复数赋值,并以与C99兼容的方式返回其实/虚部分。 解 我最终做了这样的事情: #ifdef USE_C99_COMPLEX #include typedef complex my_complex; #else typedef struct { double x, y; } my_complex; #endif /* * Those unions […]

如何告诉GCC指针参数总是双字对齐?

在我的程序中,我有一个函数,它做一个简单的向量加法c[0:15] = a[0:15] + b[0:15] 。 function原型是: void vecadd(float * restrict a, float * restrict b, float * restrict c); 在我们的32位嵌入式架构上,有一个加载/存储双字加载/存储选项,如: r16 = 0x4000 ; strd r0,[r16] ; stores r0 in [0x4000] and r1 in [0x4004] GCC优化器识别循环的向量性质并生成代码的两个分支 – 一个用于3个数组是双字对齐的情况(因此它使用双重加载/存储指令)而另一个用于数组的情况是字对齐的(它使用单个加载/存储选项)。 问题是地址对齐检查相对于加法部分是昂贵的,我想通过暗示编译器a,b和c总是8对齐来消除它。 是否有一个修饰符添加到指针声明中以告诉编译器? 用于调用此函数的数组具有aligned(8)属性,但它不会反映在函数代码本身中。 是否可以将此属性添加到函数参数中?