Tag: libc

getc()作为宏和C标准库函数定义,连贯吗?

在[7.1.4库函数的使用]中 ,我读到: 标题中声明的任何函数可以另外实现为标题中定义的函数式宏… 和 任何实现为宏的库函数的调用都应扩展为仅对其每个参数进行一次计算的代码… 然后对于getc , [7.21.7.5 getc函数] : getc函数等效于fgetc,除非它实现为宏,它可能会多次评估流,因此参数永远不应该是带有副作用的表达式。 getc的定义是: 与库函数定义相矛盾? 反过来? 这是标准中的不连贯吗? 或者这是否意味着如果getc完全实现(似乎不符合但是?)作为宏,它可能会两次评估它的参数?

矢量化的strlen逃脱阅读未分配的内存

在研究OSX 10.9.4的strlen实现时,我注意到它总是比较一个16字节的块并向前跳过到后面的16个字节,直到它遇到’\0 ‘。 相关部分: 3de0: 48 83 c7 10 add $0x10,%rdi 3de4: 66 0f ef c0 pxor %xmm0,%xmm0 3de8: 66 0f 74 07 pcmpeqb (%rdi),%xmm0 3dec: 66 0f d7 f0 pmovmskb %xmm0,%esi 3df0: 85 f6 test %esi,%esi 3df2: 74 ec je 3de0 0x10是hex的16字节。 当我看到它时,我想知道:这个记忆也可以不被分配。 如果我分配了一个20字节的C字符串并将其传递给strlen ,它将读取36字节的内存。 为什么允许这样做? 我开始寻找并发现访问数组越界有多危险? 例如,确认它绝对不是一件好事,未分配的内存可能未被映射。 然而,必须有一些东西使这项工作。 我的一些假设: OSX不仅保证其分配是16字节对齐的,而且还保证分配的“量子”是16字节的块。 换句话说,分配5个字节实际上将分配16个字节。 分配20个字节实际上将分配32个字节。 当你编写asm时读取数组的结尾本身并没有坏处,因为它不是未定义的行为,只要它在界限内(在页面内?)。 […]

-Werror = format:编译器如何知道

我写了这个故意错误的代码 printf(“%d %d”, 1); 使用g++和-Werror=format编译。 编译器给出了令人印象深刻的警告: error: format ‘%d’ expects a matching ‘int’ argument [-Werror=format] 据我所知,编译器无法判断代码是错误的,因为格式字符串直到运行时才被解析。 我的问题:编译器是否有一个特殊的function,可以用于printf和类似的libc函数,或者这是我可以用于我自己的函数的一个特性? 字符串文字?

了解C errno

我的系统errno定义为: int * __error(void); #define errno (* __error()) 我理解errno是一个宏并扩展为* __error()函数: 我到处搜索(我的系统上的源代码),但我找不到__error()函数的定义,有人可以显示/解释它的定义是什么/应该是什么? 表达式errno = 0如何使用上面的定义(将0分配给函数?)? errno = 0会扩展为* __error() = 0吗? 谢谢

达尔文真的没有mmap吗?

我试图找出如何在Mac上重新映射内存映射文件(当我想扩展可用空间时)。 我看到我们在Linux世界中的朋友都有mremap但我在Mac上的标题中找不到这样的function。 /Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h具有以下内容: mmap mprotect msync munlock munmap 但没有mremap man mremap证实了我的恐惧。 如果我想调整映射文件的大小,我当前需要munmap和mmmap ,这涉及使所有加载的页面无效。 肯定有更好的办法。 一定? 我正在尝试编写适用于Mac OS X和Linux的代码。 如果我必须这样做,我可以满足于在每种情况下使用最佳function的宏,但我宁愿正确地做。

奇怪的mktime逻辑与负秒

我一直在使用mktime / localtime进行时间管理,包括对日期/时间的一些重要算术。 当向mktime提供包含负值的struct tm时,我注意到一些非常奇怪的东西。 请参考下面的代码。 在2013年11月3日,洛杉矶有一个DST更改。如果我指定时间为2013-11-04午夜时间并减去24小时,我得到的值与2013-11-03午夜相同。 它与UTC相差25小时,这很好,因为isdst = -1可以说我们正在看’挂钟时间’。 如果我减去1440分钟(24 * 60)则相同。 但是,如果我减去86400(24 * 60 * 60)秒,我得到2013-11-03凌晨1点。 这是UTC方式的24小时差异。 这是以下代码的输出: 2013-11-03 00:00:00 (gmtoff=0, isdst=-1) -> 2013-11-03 00:00:00 (gmtoff=-25200, isdst=1) -> 1383462000 2013-12–27 00:00:00 (gmtoff=0, isdst=-1) -> 2013-11-03 00:00:00 (gmtoff=-25200, isdst=1) -> 1383462000 2013-11-04 -24:00:00 (gmtoff=0, isdst=-1) -> 2013-11-03 00:00:00 (gmtoff=-25200, isdst=1) -> 1383462000 2013-11-04 00:-1440:00 […]

OSX的x86-64程序集libc例程在哪里?

首先,一些有用的链接到OSX的Libc代码: Git: https : //github.com/aosm/Libc.git (带有OSX不同迭代的标签) HTML: http : //www.opensource.apple.com/source/Libc/ 在那里,可以看到Libc 825.40.1(OSX 10.8.5)仍然具有像memcpy这样的函数的公共asm实现。 特别是在x86_64/string/bcopy_sse42.s 。 但是,从版本997.1.1(OSX 10.9)开始,它们中的大多数似乎都消失了。 虽然有一些留在x86_64/string 。 从这里可以看到: http : //www.opensource.apple.com/source/Libc/Libc-997.90.3/x86_64/string/ 。 来源是否已关闭其他来源? 查看OSX 10.8和10.9之间的差异并不表示它们可能已移动到源树内部的位置。 调试在OSX 10.9上运行的二进制文件时,很难错过对_platform_memmove的引用。 实际上,如果我们看一下bcopy.c的来源,我们会看到: #include void bcopy(const void *src, void *dst, size_t n) { _platform_memmove(dst, src, n); } 所以也许这会产生一些有用的东西。 但由于某些原因,我找不到(_)platform_memmove ,无论是因为缺乏贪婪的能力还是宏观技巧。 有人能帮我找到吗? 编辑 :我试图寻找platform / string.h ,但就像那个邮件列表海报一样,我无法在源代码树中找到它。 编辑 :在OSX […]

realloc但只有前几个字节才有意义

假设我使用过ptr = malloc(old_size); 使用old_size字节分配内存块。 只有第一个header_size字节才有意义。 我要将大小增加到new_size 。 new_size大于old_size , old_size大于header_size 。 之前: /- – – – – – – old_size – – – – – – – \ +===============+———————+ \-header_size-/ 后: /- – – – – – – – – – – – – – – new_size – – – – – – – – […]

了解glibc源代码约定

我一直在寻找一些glibc的源代码,特别是nptl代码,我发现它有点难以理解,因为它似乎有我不熟悉的约定。 例如,我正在查看一个非常小的文件pthread_equal.c ,有一些我有疑问的事情: 22 int 23 __pthread_equal (thread1, thread2) 24 pthread_t thread1; 25 pthread_t thread2; 26 { 27 return thread1 == thread2; 28 } 29 strong_alias (__pthread_equal, pthread_equal) 第22和23行的声明看起来像我理解的东西。 它的返回类型为int然后是函数名(thread1, thread2)和参数列表(thread1, thread2) 。 但第24行pthread_t thread1;的声明是什么pthread_t thread1; 和25 pthread_t thread2; 对于? 看起来这些被声明为全局变量,但我不明白其目的。 我在nptl目录中的许多文件中都看到了这种模式,并且无法弄清楚为什么要这样做。 什么是strong_alias ? 一个快速的谷歌搜索有使用这个的例子,但我没有找到任何文档的链接。 使用两个下划线__和一些带下划线_某些名称前缀的原因是什么。 我见过的大多数代码使用了两个下划线,但我想我已经看到了一些使用下划线的地方。 例如在pthreadP.h中 556 /* Old cleanup interfaces, still used […]

如何在C中编写自己的printf()?

实际上我正在尝试使用varags在C中编写自己的printf() 。 但我没有得到正确的解决方案。 谁能帮我吗?