小编Qua*_*dom的帖子

将整数值转换为void*并在POSIX中再次返回是否总是安全的?

这个问题几乎与我发现的其他一些问题相同,但这个问题特别涉及POSIX,这是我在pthreads中遇到的一个非常常见的例子.我主要关注当前的事态(即C99和POSIX.1-2008或更高版本),但任何有趣的历史信息当然也很有趣.

问题基本上归结为b是否总是采用与以下代码中的a相同的值:

long int a = /* some valid value */
void *ptr = (void *)a;
long int b = (long int)ptr;
Run Code Online (Sandbox Code Playgroud)

我知道这通常有效,但问题是它是否是正确的事情(即,C99和/或POSIX标准是否保证它能够正常工作).

说到C99,它似乎没有,我们有6.3.2.3:

5整数可以转换为任何指针类型.除了之前指定的,结果是实现定义,可能没有正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示.56)

6任何指针类型都可以转换为整数类型.除了之前指定的,结果是实现定义.如果结果无法以整数类型表示,则行为未定义.结果不必在任何整数类型的值范围内.

即使使用intptr_t,标准似乎只能保证任何有效的void*都可以转换为intptr_t并再次返回,但它不能保证任何intptr_t都可以转换为void*并再次返回.

但是,POSIX标准仍然可以允许这样做.

我没有很大的愿望使用void*作为任何变量的存储空间(即使POSIX应该允许它我觉得它很难看),但我觉得我必须要问因为pthreads_create函数的常用示例使用了start_routine的参数是一个整数,它作为void*传入,并在start_routine函数中转换为int或long int.例如,此联机帮助页有这样的示例(请参阅完整代码的链接):

//Last argument casts int to void *
pthread_create(&tid[i], NULL, sleeping, (void *)SLEEP_TIME);
/* ... */
void * sleeping(void *arg){
    //Casting void * back to int
    int sleep_time = (int)arg;
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

我也在教科书(Peter S. Pacheco的并行编程简介)中看到了类似的例子.考虑到它似乎是一个常见的例子,人们应该比我更了解这些东西,我想知道我是否错了,这实际上是一个安全和便携的事情.

c posix pthreads c99

23
推荐指数
2
解决办法
4155
查看次数

C中的宽字符输入/输出是否始终读取/写入正确的(系统默认)编码?

我主要对类Unix系统(例如便携式POSIX)感兴趣,因为看起来Windows对于广泛的字符做了奇怪的事情.

读取和写入宽字符函数(例如getwchar()putwchar())总是"做正确的事",例如从utf-8读取并在设置区域设置时写入utf-8,或者我是否必须手动调用wcrtomb()和打印使用例如字符串fputs()?在我的系统(openSUSE 12.3)中$LANG设置为en_GB.UTF-8它们似乎做了正确的事情(检查输出我看到看起来像UTF-8,即使字符串是使用wchar_t存储并使用宽字符函数编写的).

但我不确定这是否有保证.例如cprogramming.com声明:

[宽字符]不应该用于输出,因为虚假零字节和其他具有共同含义的低ASCII字符(例如'/'和'\n')可能会散布在整个数据中.

这似乎表明输出宽字符(大概使用宽字符输出功能)可能会造成严重破坏.

由于C标准似乎根本没有提及编码,因此在使用wchar_t时我真的不知道是谁/何时/如何应用编码.所以我的问题基本上是当我的应用程序不需要知道所使用的编码时,如果只读取,编写和使用宽字符是正确的事情.我只需要字符串长度和控制台宽度(wcswidth()),所以在处理文本时使用wchar_t到处都是理想的.

c linux posix wchar-t

8
推荐指数
2
解决办法
2189
查看次数

在CMake中可移植地设置编译器选项(如-Wall和-pedantic)的最佳方法

即使我不想将我的CMakeLists文件绑定到特定的编译器,我仍然希望启用某些选项,例如-Wall,我知道许多编译器支持.

目前我这样做是为了设置-Wall和-pedantic标志,如果它们被当前编译器接受:

include(CheckCXXCompilerFlag)

check_cxx_compiler_flag(-Wall temp)
if(temp)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()
check_cxx_compiler_flag(-pedantic temp)
if(temp)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
endif()
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?或者至少有一种更好的方式来做同样的事情?以上是令人难以置信的冗长和丑陋的成就.一个更好的命令将是这样的:

enable_cxx_compiler_flags_if_supported(-Wall -pedantic)
Run Code Online (Sandbox Code Playgroud)

c++ cmake

5
推荐指数
1
解决办法
4027
查看次数

标签 统计

c ×2

posix ×2

c++ ×1

c99 ×1

cmake ×1

linux ×1

pthreads ×1

wchar-t ×1