Tag: portability

如何避免C中的整数提升?

目前尚不清楚如何使用宽字符API在C中编写可移植代码。 考虑这个例子: #include #include #include int main(void) { setlocale(LC_CTYPE, “C.UTF-8”); wchar_t wc = L’ÿ’; if (iswlower(wc)) return 0; return 1; } 使用-Wconversion选项使用gcc-6.3.0进行编译会发出以下警告: test.c: In function ‘main’: test.c:9:16: warning: conversion to ‘wint_t {aka unsigned int}’ from ‘wchar_t {aka int}’ may change the sign of the result [-Wsign-conversion] if (iswlower(wc)) return 0; ^ 为了摆脱这个警告,我们转换为(wint_t) ,就像iswlower((wint_t)wc) ,但这是iswlower((wint_t)wc)移植的。 以下示例说明了为什么它不可移植。 […]

通过config.h对sysconfdir进行可移植访问

我希望我的应用程序可以访问make install期间make install的配置文件(dist_sysconf_DATA)。 是否可以通过config.h访问$(sysconfdir) ?

什么是在C中转换字符串顺序的可移植方式

我正在尝试编写可与任何可以建立套接字连接的标准客户端进行通信的服务器(例如telnet客户端) 它最初是一个echo服务器,当然不需要担心网络字节排序。 我熟悉ntohs,ntohl,htons,htonl函数。 如果我转移16位或32位整数,或者如果发送的字符串中的字符是2或4字节的倍数,那么它们本身就会很好。 我想创建一个对字符串进行操作的函数,例如: str_ntoh(char* net_str, char* host_str, int len) { uint32_t* netp, hostp; netp = (uint32_t*)&net_str; for(i=0; i < len/4; i++){ hostp[i] = ntoh(netp[i]); } } 或类似的东西。 上面的假设是单词大小为32位。 我们不能确定发送机器上的字数不是16位还是64位正确? 对于客户端程序,例如telnet,他们必须在发送之前使用hton *,在接收数据之后使用ntoh *,对吗? 编辑:对于那些人而言,因为1-char是一个字节,字节序无关紧要: int main(void) { uint32_t a = 0x01020304; char* c = (char*)&a; printf(“%x %x %x %x\n”, c[0], c[1], c[2], c[3]); } […]

是否存在difftime占闰秒的实际系统?

C标准(ISO / IEC 9899)规定: 7.2x.2.2 difftime函数 概要 #include double difftime(time_t time1, time_t time0); 描述 difftime函数计算两个日历时间之间的差异: time1 – time0 。 返回 difftime函数以秒为单位返回以秒表示的差异。 如果结果占闰秒 ,则会使其模糊不清(我猜是故意的)。 在某些应用中,差异(从1970年到2015年7月比较时为26秒)很重要。 C标准库的大多数实现都不考虑闰秒,这是可测试的:以下(故意简洁)代码倾向于输出leap seconds accounted for from 2000/01/01 to 2015/01/01: 0 (或-473385600 )的leap seconds accounted for from 2000/01/01 to 2015/01/01: 0 -473385600如果mktime不起作用),那段时间内确实有3个闰秒。 #include #include struct tm t0,t1; // globals, thus initialized to zero […]

便携式C二进制序列化原语

据我所知,C库没有帮助将数值序列化为非文本字节流。 如我错了请纠正我。 使用的最标准工具是来自POSIX的htonl等人。 这些function有缺点: 没有64位支持。 没有浮点支持。 签名类型没有版本。 反序列化时,无符号到符号的转换依赖于有符号整数溢出,即UB。 它们的名称没有说明数据类型的大小。 它们依赖于8位字节和精确大小的uint_ N _t的存在。 输入类型与输出类型相同,而不是引用字节流。 这要求用户执行指针类型转换,这可能在对齐时不安全。 执行该类型转换后,用户可能会尝试在其本机内存布局中转换和输出结构,这种做法很糟糕,导致意外错误。 用于将任意大小的char化为8位标准字节的接口将落在C标准之间,该标准不真正确认8位字节,并且无论标准(ITU?)将八位位组设置为基本传输单位。 但旧的标准没有得到修订。 现在C11有许多可选组件,可以添加二进制序列化扩展以及线程之类的东西,而不需要对现有实现提出要求。 这样的扩展是否有用,或者担心非二进制补充机器是否毫无意义?

如何以编程方式确定“写入”系统调用对特定文件是否是primefaces的?

在某些情况下,编码器不能依赖primefaces的系统调用,例如,如果文件在NFS文件系统上。 (参见NFS概述,常见问题和HOWTO文档 )。 但是大多数数据库工作最终都需要primefaces系统调用。 (cf 数据库系统的primefaces性 )。 是否有一种标准(和OS独立)方式确认写入(和其他系统调用)在C(或python)中的特定FILE上是primefaces的。 有什么建议? 后续说明:管道的primefaces性将在下面讨论: unix管道多个编写器 如果同时通过2个不同的进程在同一文件上调用写入系统调用会发生什么 请特别注意“man”页面提取专门处理O_APPEND: 如果设置了文件状态标志的O_APPEND标志,则应在每次写入之前将文件偏移设置为文件的末尾,并且在改变文件偏移和写入操作之间不应进行中间文件修改操作。

如何将变量声明为本地可移植的线程?

C11引入了_Thread_local存储类说明符,可以与static和extern存储类说明符结合使用,将变量声明为线程局部。 GNU C编译器套件使用相同的语义实现存储类说明__thread 。 不幸的是我没有找到任何实际实现_Thread_local关键字的编译器(我尝试过gcc,clang和SUN studio)。 我目前使用以下构造来声明关键字thread_local : /* gcc doesn’t know _Thread_local from C11 yet */ #ifdef __GNUC__ # define thread_local __thread #elif __STDC_VERSION__ >= 201112L # define thread_local _Thread_local #else # error Don’t know how to define thread_local #endif 我知道这可能不适用于MSVC和其他编译器。 任何人都可以建议我一个更好的方法来声明thread_local ,使其在尽可能多的编译器中工作吗? 编辑 Christoph建议Microsoft Visual C允许__declspec(thread) 。 这是更新的宏定义: /* gcc doesn’t know _Thread_local […]

你如何编写(便携式)反向网络字节顺序?

背景 在设计二进制文件格式时,通常建议以网络字节顺序写入整数。 为此,有像htonhl()这样的宏。 但对于像WAV这样的格式,实际上使用的是小端格式。 题 无论你的代码运行的CPU是大端还是小端架构,你如何便携地编写小端值? (想法:标准宏ntohl()和htonl()可以以某种方式“反向”使用吗?或者如果代码只是运行在一个小端或大端的CPU上并选择适当的代码路径,那么它应该只测试运行时吗?) 所以问题不在于文件格式,文件格式只是一个例子。 它可以是任何类型的序列化,其中需要“线上”的小端,例如(异端)网络协议。