C89:已签名/未签名不匹配
签名/未签名的不匹配必然不好? 这是我的程序: int main(int argc, char *argv[]) { unsigned int i; for (i = 1; i
42 2024-04-22
编程技术问答社区
为什么在c99或c90模式下支持_Generic关键字?
我编写了一个简单的C程序,以测试 _generic 关键字的可用性. int main() { int _Generic; } 我使用 gcc-5.3.1 和 clang-3.8.0 编译器在ubuntu上运行了该程序. 显然,该程序在最新的C11标准中编译时会产生错误. 但是,当用 -std = C90 和 -Std = C99 标志编译时,它也会产生错误.鉴于,_ generic关键字仅在C11标准中引入. -STD =标志的行为不同吗?有没有办法测试纯C90和C99标准? 编辑: 我确实与其他标识符运行了相同的程序,这些标识符不是C11标准.喜欢: int _Hello; int _Gener; 他们成功地编译了没有任何错误或警告. 这可能是由于7.1.3,说 如果程序声明或定义了标识符 保留它的上下文(除了7.1.4允许以外)或定义保留的上下文 标识符是宏名称,行为是未定义的 @art和@lundin所说.
24 2024-04-10
编程技术问答社区
文件在MS Visual Studio中无法编译,但在GCC中可以。为什么?
我写了这样的示例代码: #include #include #include #include #include char* print_errno_msg(int value); int main(void){ struct stat buffer; int status; status = stat("./main.c", &buffer); char *msg = print_errno_msg(errno); /* syntax error : missing ';' before 'type' */ printf("status = %i; errno = %i; %s\n", status, errno, msg); /* 'msg' : undeclared identifier */ errno =
18 2024-04-10
编程技术问答社区
OpenWrt的LibUbi实现
我正在尝试使用libuci开发一个为OpenWRT路由器编写的应用程序(编写ANSI C). 我已经阅读了这篇有用的文章:如何找出ETH0模式是静态还是DHCP? ,我已经开发了我的应用程序,该应用程序能够使用UCI库读取网络数据(在这种情况下,如果启用了PPP). char path[]="network.ppp.enabled"; struct uci_ptr ptr; struct uci_context *c = uci_alloc_context(); if(!c) return; if (strcmp(typeCmd, "GET") == 0){ if ((uci_lookup_ptr(c, &ptr, path, true) != UCI_OK) || (ptr.o==NULL || ptr.o->v.string==NULL)) { uci_free_context(c); ret
22 2024-04-09
编程技术问答社区
ANCI C(C90): const可以改变吗?
我对ANSI规范所说的有关更改声明const的说法可以通过其地址法律修改.不幸的是,我无法访问C90规格,但指针相互矛盾: 关键字const不会将变量变成常数!带有const的符号 预选赛仅意味着该符号不能用于分配.这使价值 通过那个符号重新进行广告;它不会阻止值通过修改的值 其他一些意味着该程序的内部(甚至外部).这几乎只有有用 对于限定指针参数,指出此函数不会更改参数指向的数据,但其他函数可能会更改. (专家C编程:深C秘密:Peter van der Linden) 如果尝试通过使用具有非统一合格类型的LVALUE来修改用constemified类型定义的对象,则该行为是不确定的.如果尝试通过使用具有非挥发性合格类型的LVALUE来指定用挥发性合格类型定义的对象,则该行为是不确定的. ( http://flash-genger-gordon.me.uk/ansi.uk/ansi.c.txtxtx) 我在C99规格(N1256.pdf)中看到了后者. 任何人都
6 2024-04-09
编程技术问答社区
在隐式函数声明的情况下,默认参数的推广。
我试图在旧问题中搜索,但我没有解决我的问题. 我试图解释我的疑问; 假设在C89模式下工作,如果在函数调用之前没有该函数的原型,则该函数有隐式声明,该函数的类型为int,并且参数通过默认参数促销进行转换: 类型char或short int的对象(是否签名)是 适当地晋升为INT或未签名的INT;然后 浮点类型的对象被提升为双键. 所以,如果我写这样的代码,我同意它必须有效: int main(void){ char a; short b,c; f(a,b,c); return 0; } int f(int a,int b,int c){ return 1; } 在这里相同: int main(void){ float a; short b,c; f(a,b,c); return 0; } int f(double a,int b,int c){ return 1; }
50 2024-04-09
编程技术问答社区
用NULL指针作为数组结束的标记
我阅读了Kernigan&Ritchie的《 C编程语言》第二版的第6.3段. 一些结构: struct key { char *word; int count; } keytab[NKEYS] { { "auto", 0 }, { "break", 0 }, { "case", 0 }, { "char", 0 }, { "const", 0 }, { "continue", 0 } }; 作者写了有关它的文章: 数量nkeys是keytab中的关键字数量.虽然我们 可以手头来计算这一点,这样做要容易得多,更安全地做到这一点 机器,特别是如果列表可能会更改. 一种可能性 将用空指针终止初始化器列表, 然后沿keytab循环直到找到末端. 如果枚举仅包含指针: struct key { char *word; char *description; } keytab[NKE
4 2024-04-09
编程技术问答社区
在windows平台上使用ansi | c,我可以获得精确到毫秒的系统时间吗?
我需要获得毫秒的精度.我看看这个问题在Windows上工作:它给出了POSIX函数的链接错误. ,如果我以毫秒精度获得UTC的时间,那将是非常好的. 解决方案 不在ANSI C中,但是Windows API提供GetSystemTime function as illustrated here: 其他解决方案 对不起,但是您不能使用ANSI C或Windows API进行此操作. you can 使用getSystemtime或使用getSystemtimeasfiletime使用getSystemtime或使用100纳秒分辨率使用毫秒获得系统时间,但是>准确性不会那么好.系统时间仅在每个时钟间隔更新,该时间间隔在10-15毫秒左右的位置,具体取决于基础体系结构(SMP,Uniprocessor,...). 有多种方法可以使用不同复杂性的不同算法来推断系统时间,但是如果没有操作系统的支持,您将永远无法保证正确的高分辨率时钟时间. 其他解决方案 Wind
30 2024-04-09
编程技术问答社区
根据C标准的严格解释,允许对一个可能无效的指针进行操作
原始问题 (请参阅"编辑:更新的方案") 这个问题可能以一种或另一种方式重复,围绕着指示器的不确定行为的大量问题,这些问题涉及到范围之外的对象等.但是我在此处发现的所有问题都大多是专业用例.因此,我想颠倒地将问题旋转,不要问是否禁止某事,但是到底允许什么? 有一个可能的方案:您有一个函数,可以采用指针 - 您不知道它是否来自(仍然)有效的对象.哪些操作在的所有情况下 不确定的行为?哪个可能没有指定的侧面条件? int * myFunc(const int * const A, int * B) { ... } 编辑:更新的secenario 在对问题的评论和 Matt McNabbs答案 指出,无论如何,UB很可能已经上升了,因为在场景中调用函数期间,使用无效的指针(S值).因此,我将稍微更改场景(按照 keith href="https://stackoverflow from示例. int *ptr = malloc(sizeof *ptr)
24 2024-04-09
编程技术问答社区
在每个C标准中,带空括号的函数指针的语义是什么?
回答 this and 在带有GCC的i386系统上,"额外"的参数在呼叫空的parenthess-type'd功能指针中传递了,因为堆栈帧的工作原理.例如, /* test.c */ #include int foo(int arg) { return arg; } int main(void) { int (*fp)() = foo; printf("%d\n", fp(267239151, 42, (struct { int x, y, z; }){ 1, 2, 3 })); return 0; } $ gcc -o test test.c && ./test 267239151 $ 在哪些C标准中是空位的功能指针?无论如何,他们指定什么意思? 解决方案 使用具有空括号的功能声明器(不是 原型 - 格式参数类型声明器)是一个过时的 功能. 同样的措辞出现在1990年,1999年和2011年的ISO C标
12 2024-04-09
编程技术问答社区
安全浮点除法
我的代码中有一些位置,我想确保2个任意浮点数(32位单个精度)的划分不会溢出.目标/编译器不能保证(明确地)对-inf/inf的良好处理,并且(无法完全保证IEEE 754对于特殊值 - (可能是未定义的) - 并且目标可能会改变).另外,我不能在这个特殊位置的输入上保存假设,并且我属于C90标准库. 我已经阅读了每个计算机科学家应该知道什么点算术但是说实话,我有点迷路了. 所以...我想问社区,以下代码是否可以解决问题,并且是否有更好的/更快/更快/更正确的方法: #define SIGN_F(val) ((val >= 0.0f)? 1.0f : -1.0f) float32_t safedivf(float32_t num, float32_t denum) { const float32_t abs_denum = fabs(denum); if((abs_denum
6 2024-04-09
编程技术问答社区
结构指针的转换
我正在尝试实现这样的链接列表: typedef struct SLnode { void* item; void* next; } SLnode; typedef struct DLnode { void* item; void* next; struct DLnode* prev; } DLnode; typedef struct LinkedList { void* head; /*SLnode if doubly_linked is false, otherwise DLnode*/ void* tail; /* here too */ bool doubly_linked; } LinkedList; 我想这样访问它: void* llnode_at(const LinkedList* ll, size_t index) { size_t i; SLnode* current;
8 2024-04-09
编程技术问答社区
ANSI C: 如果一个函数指针指向可执行代码,是否意味着比简单调用函数的执行开销更少?
我们知道,在适当的方案中使用C中的C函数指针可能会很有帮助(在运行时与编译时间调用功能,使代码更可读等),但是围绕简单的文献却没有太多的文献使用功能指针的功能调用VS. void foo(void) { printf("hello\n"); } int testFcn(void) { // simple invokation foo(); return 0; } // Or, declare function pointer and assign void (*myFunc)(void) = foo; int testFcn(myFunc) { // Function pointer invokation. myFunc(); return 0; } 也许唯一真正的告诉的方法是分析.lst文件和.map文件? 解决方案 在一般情况下,当功能指针存储在数据段的内存中时,通过这种指针调用函数将涉及更多开销
8 2024-04-09
编程技术问答社区
用前C99编译器构建C语言迭代器宏
我的代码必须与前C99编译器一起编译(我们正在努力更新,但这是一项巨大的任务),正在召集使用C99设计的公用事业库.特别是,这些实用程序定义了hashmap类型,并提供了与以下几个相似的迭代宏: : #define MAP_FOREACH(key, val, map) \ for (struct _map_iterator iter __attribute__((cleanup(_map_iter_cleanup))); \ (key) = iter->pair->key, \ (value) = iter->pair->value; \ iter = iter->get_next_cb()) 实际代码具有更多的内容(确保迭代器的名称是唯一的功能等),但这涵盖了我的问题的肉,即C 1999年之前的C不支持初始化变量内部循环.现在,这里明显的解决方案是将初始化移到循环外,其代码看起来像: // Doesn't wor
8 2024-04-09
编程技术问答社区
C90中的可变长度结构
GNU C中允许 零长度阵列. 可以初始化,因此 struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length; 注意:我在此处引用此页面: http:http://gcc. gnu.org/onlinedocs/gcc/zero-length.html (在c)中提供了可变长度结构的基本介绍. 继续说:"在ISO C90中,您必须给内容1个长度为1,这意味着您要么浪费空间或使参数复杂化." 这是什么意思?有人可以提供一个示例,说明如何在C90中初始化可变长度结构以帮助理解? 解决方案 如果您确实必须使用C90,则 c FA
16 2024-04-09
编程技术问答社区
单一参数的主程序
我最近遇到了一个C程序,其中主要函数仅处理一个参数.这是C89合法的吗? GCC似乎没有任何问题. 我认为发生的是签名被忽略,主被称为main(int,char**),但我不确定. 在程序中看起来像这样: main(argc) { ... } 解决方案 根据C89标准,这是不合法的.从 2.1.2.2节托管环境: The function called at program startup is named `main`. The implementation declares no prototype for this function. It can be defined with no parameters: int main(void) { /*...*/ } or with two parameters (referred to here as argc and argv , though any names may be used, as
18 2024-04-09
编程技术问答社区
C90中的Linux内核container_of宏和通用容器
是否可以实现我要问的是因为我想在C90中实现一个通用容器,类似于内核的链接列表.我想的实际容器是一个测序集,类似于您从提升多索引. 解决方案 在container_of()的内核定义中使用typeof仅用于编译时类型检查 - 它确保传递的ptr确实是与member相同类型的指针.它可以以这种类型检查为代价进行修改为完全是ANSI C: #define container_of(ptr, type, member) ((type *)((char *)ptr - offsetof(type, member))) (offsetof()在中) 其他解决方案 是. 诀窍是替换化合物表达式和用于输入检查的typeof.可以通过替换(ptr)的评估来完成: (1 ? (ptr) : &((type*)0)->member) 条件运算符始终返回第一个操作数,因为其选择操作数为1.此外,?:操作数的类型必须兼容强迫类型从编译器进行检查. 最
22 2024-04-08
编程技术问答社区
Visual Studio的C4028警告(正式参数与声明不同)是否虚假?
考虑以下功能声明和定义.在标题文件中: void some_function(int param); 在源文件中: #include "test.h" void some_function(const int param) {} int main(void) { return 0; } 在Visual Studio 2010下,我认为warning C4028: formal parameter 1 different from declaration汇编为纯C项目.但据我所知,这是完全有效的C,并且是相当普遍的实践. 我对此有错吗,VS2010因此警告我是否正确?或者,如果这是虚假的警告,我可以专门为这种情况禁用它,但请继续警告的实际情况不匹配的参数类型? (VS2010随附的实际编译器是: Microsoft(r)32位C/C ++优化编译器版本16.00.30319.01 for 80x86 .我的命令行只是cl test.c.)/p>
14 2024-04-08
编程技术问答社区
使用单值指针作为数组
(请注意,"寄存器"变量扩展了问题) 我的问题简而 int a = 0; int b = (&a)[0]; const int c = 0; b = (&c)[0]; 问题扩展: stackoverflow.com/users/366377/jens-gustedt"> jens gustedt 建议不允许进行注册变量的地址.这是真的?一个人还可以从标准中提供其他引用,以推理这一点? /* Question extension */ register int d = 0; int e = (&d)[0]; 背景: i有一组数组,代表对象的结构化集合的属性 - 对于每个属性一个数组.因此,阵列是该结构化集合的线性化.这些属性数组元素都与不同的值相比,具体取决于结构化集合中对象的位置.这些值也以与集合的结构OD相连的方式结构:-) 属性数组可能是不同类型的每个类型. 所以我写了一个宏,它在所有属性上进行迭代(给定的任何属性数组),并在Fly结构信息上提供,
18 2024-04-08
编程技术问答社区
是否保证`long`与`size_t`一样宽?
寻找unsigned long的证据时,足以持有size_t,以便成为printf的目的,我遇到了两个事实(oid)s. 首先,有一个答案表明long确实不能保证足够大于size_t.另一方面,我看到了这个答案建议在pre c99,x中使用printf("%lu", (unsigned long)x) . 因此,您可以假设还是保证long足以在 pre c99 中保存size_t.另一个问题是是否存在任何保证size_t适合其他标准化整数类型(除了ssize_t,ptrdiff_t之类的明显例外). 解决方案 没有这样的保证. 虽然实现具有相同大小的long和size_t>的常见,但并非总是如此.如注释中的评论,Windows 64位具有不同的尺寸,对于long和size_t. 还注意到,实现的最小值为65535,而ULONG_MAX的最小值为2147483647(2147483647 for LONG_MAX). (请注意,SIZE_MAX以C99出现.
16 2024-04-08
编程技术问答社区