小编R..*_*R..的帖子

为什么POSIX指定wctomb为非线程安全的,但不是mbtowc?

在XSH 2.9.1中,wctomb列为不需要线程安全的函数之一.但是,相反的转换函数mbtowc不会出现在列表中.在使用转换状态的编码的实现上,既没有线程安全的API,也没有必要要求一个是线程安全的而另一个不是,而在没有禁止有状态编码的情况下它们都不是线程安全的.

同样地wcstombs(在列表中)和mbstowcs(不是).由于这两个函数都在整个字符串上运行,这些字符串在初始移位状态下开始和结束,因此它们不是有状态的,它们的API是线程安全的,而且一个方向被指定为线程安全而不是没有意义其他.

任何人都可以对此有所了解吗?

c posix thread-safety multibyte

17
推荐指数
1
解决办法
921
查看次数

通过示例了解限制限定符

restrict关键字的行为在C99定义由6.7.3.1:

设D是普通标识符的声明,它提供了一种将对象P指定为类型T的限制限定指针的方法.

如果D出现在块内并且没有存储类extern,则让B表示该块.如果D出现在函数定义的参数声明列表中,则让B表示关联的块.否则,让B表示主块(或在独立环境中在程序启动时调用的任何函数块).

在下文中,指针表达式E被称为基于对象P if(在评估E之前执行B中的某个序列点)修改P以指向其先前指向的数组对象的副本将改变E.119的值)注意''based''仅为具有指针类型的表达式定义.

在每次执行B期间,让L为具有基于P的&L的任何左值.如果L用于访问它指定的对象X的值,并且X也被修改(通过任何方式),则以下要求适用:T不应该是const限定的.用于访问X值的每个其他左值也应具有基于P的地址.出于本子条款的目的,每次修改X的访问也应被视为修改P. 如果为P分配了指针表达式E的值,该指针表达式E基于与块B2相关联的另一个受限指针对象P2,则B2的执行应在执行B之前开始,或者B2的执行应在该执行之前结束.分配.如果不满足这些要求,则行为未定义.

就像其他人一样,我很难理解这个定义的所有复杂性.作为这个问题的答案,我希望看到第4段中每个要求违反要求的一些好例子.本文:

http://web.archive.org/web/20120225055041/http://developers.sun.com/solaris/articles/cc_restrict.html

在"编译器可能假设......"方面做得很好.扩展该模式并将编译器可以做出的假设以及它们如何无法保持,每个示例都很棒.

c c99 strict-aliasing restrict-qualifier

17
推荐指数
1
解决办法
2539
查看次数

HTML版C标准草案(n1256.pdf)?

是否有HTML版本的n1256.pdf(ISO C99 + TC3),或推荐的方式将其转换为html或另一种不那么痛苦的浏览格式?我尝试过的所有pdf转换器都给出了非常糟糕的结果,特别是在未能将"fi"连字转换为更容易搜索的内容时,而且仅仅是基本格式化.

以下是原始参考:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

c pdf standards

16
推荐指数
1
解决办法
2686
查看次数

glibc/NPTL/Linux强健互斥体中的竞争条件?

在对2010年自动在Unix上崩溃时自动释放互斥锁的问题的评论中,jilles声称:

glibc强大的互斥体非常快,因为glibc采用危险的快捷方式.当内核将其标记为"将导致EOWNERDEAD"时,无法保证互斥锁仍然存在.如果互斥锁被破坏并且内存映射文件替换为内存映射文件恰好包含在正确位置的最后一个拥有线程的ID而最后一个拥有线程在写入锁定字之后终止(但在从其列表中完全删除互斥锁之前)拥有的互斥锁),文件已损坏.Solaris和will-be-FreeBSD9强大的互斥体速度较慢,因为它们不想冒这个风险.

我无法理解索赔,因为除非它被解锁(因此不在任何线程的强大列表中),否则销毁互斥锁​​是不合法的.我也找不到任何搜索这样的错误/问题的参考资料.索赔是否只是错误的?

我问的原因和我感兴趣的是,这与我自己实现的相同Linux robust-mutex原语的正确性有关.

c linux pthreads

16
推荐指数
2
解决办法
1074
查看次数

C将内存部件移动到位

我正在实现几个数据结构和一个我要使用的原语如下:我有一个内存块A [N](它有一个可变长度,但我的示例需要100)并且在这个块中,有一个较小的部分C长度为K(比方说30),我想移动而不使用任何额外的内存.

另外的困难是,A"包裹",即C可以从A [80]开始,然后C的前20个元素是元素A [80..100],最后10个元素是元素A [ 0..10].此外,目标范围还可以以任何可能的方式"包裹"并与C重叠.另外,我不想使用超过一定数量的额外内存,一切都应该到位.此外,既不在目标范围内也不在源范围内的A部分可能包含重要的内容,因此也不能使用.所以一个案例如下:

A看起来像这样:

| 456789ABCDEF0123456789AB | ----- | 0123 |

应该转变为:

| 89AB | ----- | 0123456789ABCDEF01234567 |

只是将它委托给一个库或者使用库中的另一个数据结构不是一个选项,我想自己理解这个问题.在第一眼看来,我认为它可能不是微不足道的,但是一旦你区分了一些案例,它就会变得清晰,但现在我遇到了严重的麻烦.当然,如果它们不重叠或不包装,则存在微不足道的情况,但至少如果两者同时发生,则会变得混乱.您可以从一个空闲位置开始移动属于那里的部件,然后在其他地方创建另一个自由部件,并且很难跟踪您可以使用哪些部件.

也许我完全错过了一些东西,但即使是我的特殊情况,如果目标范围没有换行也有近100行(虽然它的一半是断言和注释)我可以更新它以便它也处理一般情况下一些额外的索引计算,但如果有人有一个优雅而简短的解决方案,我将不胜感激.直觉上我认为这应该是微不足道的,但我还没有看到最好的解决方案.

注意:有趣的情况当然是,如果C几乎和A一样大.如果| C | <N/2,这是微不足道的.

编辑:使用超过一定数量的额外标志/索引计数作为额外的内存,我想尽可能避免这种情况.

编辑:有些人想看我的代码.我的问题相当抽象,所以我不想发布它,但也许有人会看到如何改进它.这很糟糕,它只适用于目标从头开始(但是,可以很容易地改变)并且非常长的情况,但是它在O(n)中没有额外的存储器的情况下完成工作.

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

void move_part(int* A, size_t N, size_t target, size_t source, size_t size, int show_steps)
{
  assert(source + size <= N);
  assert(target + size <= N);
  if (show_steps) {
    printf("Moving size %d from %d to %d.\n", size, source, target);
  }
  memmove(A + target, …
Run Code Online (Sandbox Code Playgroud)

c language-agnostic memory algorithm permutation

16
推荐指数
1
解决办法
1488
查看次数

比特域的类型是什么?

我在C标准中找不到指定的任何地方.例如,在

struct { signed int x:1; } foo;
Run Code Online (Sandbox Code Playgroud)

foo.x一个类型的左值int,还是其他什么?int因为你不能在其中存储任何类型的值int,只有0或-1,但它找不到任何类型的语言,这似乎是不自然的.当然,在大多数表达式中使用它,int无论如何它都会被提升,但是实际的类型在C11中有所不同_Generic,而且我在标准中找不到任何关于位域如何与之交互的语言_Generic.

c language-lawyer bit-fields c11

16
推荐指数
2
解决办法
3059
查看次数

程序可能检测NULL是用整数还是指针类型定义的方法?

C允许NULL定义为任何空指针常量,换句话说,任何求值为0的整型常量表达式,或者这样的表达式转换为void *.我的问题是关于定义的选择是否真正重要,即一个否则正确的程序是否可能取决于使用哪个定义.出于这个问题的目的,我想忽略诸如NULL传递给可变函数或缺少原型的函数之类的问题,因为我已经单独处理过它.让我们假设sizeof NULL == sizeof(void *)并且sizeof NULL == sizeof(T)对于某些整数类型T,因此这sizeof不足以回答是否NULL具有指针类型的问题.

显然,C11提供了一种区分类型NULL或任何其他表达式的方法:_Generic关键字.

C99还提供了一种看似可靠的模糊方法:

int null_has_ptr_type()
{
    char s[1][1+(int)NULL];
    int i = 0;
    return sizeof s[i++], i;
}
Run Code Online (Sandbox Code Playgroud)

是否有其他方法NULL可以通过符合C的程序确定类型?任何在C89工作的人?

c language-lawyer

16
推荐指数
1
解决办法
1122
查看次数

使得64位的普通int会破坏很多合理的代码吗?

直到最近,我还是考虑过大多数系统实现者/供应商的决定,int即使在64位机器上保持简单的32位也是一种权宜之计.随着现代C99固定大小的类型(int32_tuint32_t等)的需要为了有每个大小为8,16,32的一个标准的整数类型,和64大多消失,并且它似乎是int也可以同样进行64位.

然而,intC 中普通大小的最大实际结果来自于C基本上没有小于int类型的算术.特别是,如果int大于32位,则对uint32_t值的任何算术运算的结果都具有类型signed int,这相当令人不安.

这是否是int在实际实现中永久固定为32位的一个很好的理由?我倾向于说是的.在我看来,uint32_tint大于32位时,可能存在大量的使用.即使应用一元减号或按位补码运算符也会变得危险,除非你再次使用uint32_t.

当然,同样的问题也适用于uint16_tuint8_t当前实现,但大家似乎都知道,并用于把它们当作"小-于─ int"类型.

c 64-bit integer-promotion

15
推荐指数
2
解决办法
641
查看次数

为什么OSX将atoi/atof记录为不是线程安全的?

我知道strtol和strtof比atoi/atof更受欢迎,因为前者检测错误,而且当涉及非base-10时,strtol比atoi更灵活.

但我仍然对某些事情感到好奇:OS X上的'man atoi'(或atof)(虽然不在Linux上!)提到atoi/atof不是线程安全的.坦率地说,我很难想象atoi或atof的可能实现是不是线程安全的.有人知道为什么手册页会这么说吗?这些功能在OS X或任何其他平台上实际上是不安全的吗?如果它们是,那么为什么图书馆不会根据strtol定义atoi,因此是安全的?

c macos

15
推荐指数
1
解决办法
2552
查看次数

计算x mod y,其中y不能表示为浮点

作为规范示例,考虑三角函数的参数减少问题,如计算xmod2π作为计算sin(x)的第一步.这种问题很难,因为你不能只使用fmod,因为y(在例子中为2π)不具有代表性.

我提出了一个简单的解决方案,适用于任意值y,而不仅仅是2π,我很好奇它是如何比较(性能)与典型的参数减少算法.

基本思想是将一个包含2 n mod y 值的表存储在log2(y)范围内的每个值n到最大可能的浮点指数,然后使用模运算的线性,将此表中的值相加在x的值中设置的位.它相当于N个分支和最多N个加法,其中N是浮点类型中的尾数位数.结果不一定小于y,但是它受N*y的限制,并且可以再次应用该过程以给出由log2(N)*y限定的结果,或者fmod可以简单地在此处使用具有最小误差的结果.

这可以改善吗?并且典型的三角参数约简算法是否适用于任意y或仅适用于2π?

language-agnostic math floating-point modulo

15
推荐指数
1
解决办法
564
查看次数