Tag: c11

如何在独立的C或C ++实现中理解primefaces?

C11和C ++ 11根据执行线程定义primefaces。 而在托管环境中,很清楚线程是什么,在独立语言实现中它是一个模糊的术语。 如何在独立实现中正式理解C11和C ++ 11中指定的primefaces,其中所有线程必须在程序内实现? 例如:ISR是一个单独的执行线程吗? 为什么标准委员会根据线程而不是简单地在代码排序领域定义primefaces? 除了gcc之外,是否有任何嵌入式编译器已经支持C11 / C ++ 11primefaces?

(uint64_t)-1是否保证产生0xffffffffffffffff?

我知道,C标准很好地定义了(unsigned)-1必须产生2 ^ n-1,即一个无符号整数,其所有位都置位。 (uint64_t)-1ll 。 但是,我在C11标准中找不到指定如何解释(uint64_t)-1内容。 所以,问题是:C标准是否有任何保证,以下哪项适用? (uint64_t)-1 == (uint64_t)(unsigned)-1 //0x00000000ffffffff (uint64_t)-1 == (uint64_t)(int64_t)-1 //0xffffffffffffffff

如果您知道在到达有效区域的末尾之前找到该字符,那么调用长度过长的memchr是否合法?

在C11和C ++ 11 1中是否有以下定义的行为? bool has4() { char buf[10] = {0, 1, 2, 4}; return memchr(buf, 4, 20); } 在这里,我们通过一个太长的长度memchr 。 数组有10个元素,但是我们传递了20.但是,我们搜索的元素总是在结束之前找到。 我很清楚这是否合法。 如果允许这样做,则会限制实现的灵活性,因为实现不能依赖于大小是可访问存储器区域大小的有效指示,因此必须小心读取超出找到的元素。 一个例子是希望从传入指针开始执行16字节SIMD加载然后并行检查所有16个字节的实现。 如果用户传递的长度为16,则只有在需要访问整个长度时才会安全。 否则(如果上面的代码是合法的),实现必须避免对目标元素之外的元素进行潜在的error handling,例如通过对齐加载(可能很昂贵)或检查指针是否接近保护边界的末尾 。 1这是一个罕见的问题,我猜C和C ++的标记是有效的:据我所知,C ++标准只是在行为方面直接推迟到C标准,但是如果不是这样的话我想知道。

由C11 aligned_alloc分配的内存重新分配是否保持对齐?

请考虑以下(C11)代码: void *ptr = aligned_alloc(4096, 4096); … // do something with ‘ptr’ ptr = realloc(ptr, 6000); 由于ptr指向的内存与aligned_alloc有一个4096字节的对齐,它(读取:是否保证)在(成功)调用realloc之后保持该对齐? 或者内存可以恢复为默认对齐方式?

什么ABI,如果有的话,限制 intmax_t的大小?

从1999版本开始,ISO C标准定义了一个标准头文件 ,它定义了typedef intmax_t和uintmax_t 。 它们分别指定“能够表示任何(有符号|无符号)整数类型的任何值的一个(有符号|无符号)整数类型”。 例如,如果典型地,最宽的有符号和无符号整数类型是long long int和unsigned long long int ,两者通常都是64位,那么intmax_t和uintmax_t可能在定义如下: typedef long long int intmax_t; typedef unsigned long long int uintmax_t; 有一组有限的预定义有符号和无符号整数类型,范围从signed , unsigned和plain char到signed和unsigned long long int 。 C99和C11还允许实现定义扩展的整数类型 ,这些类型不同于任何标准类型,并且具有实现定义的关键字的名称。 gcc和clang在某些但不是所有目标上都支持__int128和unsigned __int128类型。 这些行为类似于128位整数类型,但它们不被视为扩展整数类型 ,并且两个编译器的文档都声明它们不支持任何扩展整数类型。 由于这些不是整数类型,因为标准定义了术语,因此intmax_t和uintmax_t适用于64位类型,而不是128位类型。 这些都不违反C标准(实现不需要具有任何扩展的整数类型,并且只要它们不破坏任何严格符合的程序,它们就被允许具有任意扩展)。 但在我看来,将__int128和unsigned __int128视为扩展整数类型,并将intmax_t和uintmax_t视为128位类型是intmax_t uintmax_t 。 不这样做的基本原理是改变intmax_t和uintmax_t的大小将是“ABI不兼容的变化”。 Clang C ++状态页面在脚注(5)中说: 对于没有提供任何扩展整数类型的Clang等实现,不需要进行编译器更改。 __int128不被视为扩展整数类型,因为更改intmax_t将是ABI不兼容的更改。 (是的,这主要讨论C ++,但规则与C相同) 在gcc错误报告中 ,声称: sizeof(intmax_t)由各种LP64 […]

可以使用C11围栏来推断其他线程的写入吗?

图4b中的Adve和Gharachorloo的报告提供了以下在没有顺序一致性的情况下表现出意外行为的程序示例: 我的问题是,是否有可能只使用C11栅栏和memory_order_relaxed加载和存储来确保register1(如果写入)将被写入值1.抽象中可能难以保证的原因是P1,P2并且P3可以在病理性NUMA网络中的不同点处具有P2在P3之前看到P1的写入的属性,但是不知何故P3看到P2的写入非常快。 特别是对C11规范难以保证的原因是P1写入A和P2的A读取不会相互同步,因此规范的5.1.2.4.26段将导致未定义的行为。 可能我可以通过放松的primefaces提取/存储来回避未定义的行为,但我仍然不知道如何对P3所看到的顺序进行过渡性推理。 下面是一个试图用栅栏解决问题的MWE,但我不确定它是否正确。 我特别担心释放栅栏不够好,因为它不会刷新p1的存储缓冲区,只是p2的。 但是,它会回答我的问题,如果你可以认为断言永远不会失败只是基于C11标准(而不是一些关于特定编译器和架构的其他信息)。 #include #include #include #include atomic_int a = ATOMIC_VAR_INIT(0); atomic_int b = ATOMIC_VAR_INIT(0); void p1(void *_ignored) { atomic_store_explicit(&a, 1, memory_order_relaxed); } void p2(void *_ignored) { if (atomic_load_explicit(&a, memory_order_relaxed)) { atomic_thread_fence(memory_order_release); // not good enough? atomic_store_explicit(&b, 1, memory_order_relaxed); } } void p3(void *_ignored) { int register1 = 1; if (atomic_load_explicit(&b, […]

使用C scanf_s输入字符串

我一直在努力寻找答案,但我找不到答案。 我想插入一个读取字符串的部分,如“Hello”字符串并存储并可以在需要时显示它,以便printf(“%s”, blah); 产生Hello 。 这是给我带来麻烦的代码部分 char name[64]; scanf_s(“%s”, name); printf(“Your name is %s”, name); 我知道printf不是问题; 在提示输入某些内容后程序崩溃。 请帮忙?

你可以将“指向函数指针的指针”转换为void *

灵感来自对我的回答的评论。 这一系列步骤在C标准(C11)中是否合法? 创建一个函数指针数组 获取指向第一个条目的指针并将该指针转换为函数指针 void* 对该void*执行指针算术void* 将其强制转换为指向函数指针的指针并取消引用它。 或者相当于代码: void foo(void) { … } void bar(void) { … } typedef void (*voidfunc)(void); voidfunc array[] = {foo, bar}; // Step 1 void *ptr1 = array; // Step 2 void *ptr2 = (char*)ptr1 + sizeof(voidfunc); // Step 3 voidfunc bar_ptr = *(voidfunc*)ptr2; // Step 4 我认为这是允许的,因为实际的函数指针只能通过正确的类型指针访问。 但Andrew Henle指出, […]

对memcpy_s的未定义引用

我正在尝试修复对memcpy_s()错误的未定义引用。 我在我的文件中包含了string.h , memcpy()函数运行正常,我也尝试过包含memory.h 。 我在x64 Windows 7上并使用gcc 4.8.1进行编译。 #include #include #include void doMemCopy(char* buf, size_t buf_size, char* in, int chr) { memcpy_s(buf, buf_size, in, chr); } buf内存已在main函数中分配,该函数调用doMemCpy(buf, 64, in, bytes) 。 in是从标准输入读取的字符串 来自cmd终端的确切错误: 未定义引用“memcpy_s”collect2.exe:错误:ld返回1退出状态

为什么在C中的等式表达式中不允许使用结构?

结构体作为比较操作数的不可用性是C中比较明显的事情之一(对我而言)没有多大意义。 结构可以通过值传递并通过赋值复制,但是没有为它们指定== 。 下面是C11标准(草案)的相关部分,它们定义了相等运算符( ==和!= )和简单赋值运算符( = )的约束。 注意在等式运算符的约束中缺少结构和联合。 (除了缺乏处理_Atomic ,C99中的措辞是相同的)。 6.5.9平等运营商 约束 以下其中一项应持有: 两个操作数都有算术类型; 两个操作数都是指向兼容类型的限定或非限定版本的指针; 一个操作数是指向对象类型的指针,另一个是指向void的限定或非限定版本的指针; 要么 一个操作数是一个指针,另一个是空指针常量。 6.5.16.1简单分配 约束 以下其中一项应持有: 左操作数具有primefaces,限定或非限定算术类型,右边有算术类型; 左操作数具有与右侧类型兼容的结构或联合类型的primefaces,限定或非限定版本; 左操作数具有primefaces,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,左侧指向的类型具有全部右边指出的类型的限定词; 左操作数具有primefaces,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的指针void,左边指向的类型具有右边指向的所有类型的限定符; 左操作数是一个primefaces,限定或非限定指针,右边是一个空指针常量; 要么 左操作数的类型为atomic,qualified或nonqualified _Bool,右边是指针。 任何人都可以解释为什么存在这种差异(没有推测)?