小编Aja*_*iya的帖子

在类型之间以字节方式复制数据会破坏严格的别名吗?

假设我有两种类型AB相同的大小,我有两个变量

A a = ... ; // Initialized to some constant of type A
B b;
Run Code Online (Sandbox Code Playgroud)

如果我将内容复制ab使用类似的东西 -

assert(sizeof(A) == sizeof(B));
size_t t;
for( t=0; t < sizeof(A); t++){
    ((char*)&b)[t] = ((char*)&a)[t];
}
Run Code Online (Sandbox Code Playgroud)

这会破坏C的严格别名规则吗?我知道投射指针char*并且读取它不是UB但是我担心转让中涉及的两个derefences.

如果这不是UB,这可能是一种有效的打字方式吗?

c undefined-behavior language-lawyer

10
推荐指数
1
解决办法
171
查看次数

将 T[][] 转换为 T*

将类型T为2D 的数组T*强制转换为元素并取消引用元素是否安全?

由于二维数组的内存布局是线性的,因此基指针应该等于指向第一个元素的指针。由于它们指向的最终类型也是相同的,因此不应该存在任何对齐差异问题。

或者有一些方面会导致未定义的行为?

为了清楚起见,我的意思是这样的 -

int arr[10][10];
int p = *((int*) arr);
Run Code Online (Sandbox Code Playgroud)

另外,如果我访问第一个数组之外的元素,即 (int*) arr + 13,同样的问题。它是否属于越界访问的条款?因为我在第一个数组的边界之外访问。

c arrays pointers undefined-behavior

7
推荐指数
1
解决办法
174
查看次数

为什么printf中的格式标记为restrict?

我刚碰巧看了printf(和其他fprintf类函数)的原型-

int printf(const char * restrict format, ...);
Run Code Online (Sandbox Code Playgroud)

restrict如果我理解正确的关键字,如果标记了其中一个,则禁止通过两个指针访问同一个对象restrict.

这里引用了与C标准相同的例子.

restrict我认为标记格式的一个好处是保存函数,使其不会在执行期间修改格式字符串(比如因为%n格式说明符).

但这是否会产生更大的约束?这会使以下函数调用无效吗?

char format[] = "%s";
printf(format, format);
Run Code Online (Sandbox Code Playgroud)

因为这里有明显的别名.为什么将restrict关键字添加到format参数中printf

c printf restrict

7
推荐指数
1
解决办法
608
查看次数

使用 ld 创建非 PIC 共享库

我有一堆在没有该-fPIC选项的情况下编译的目标文件。因此对函数的调用不使用@PLT. (源代码是 C 语言并用 编译clang)。

我想将这些对象文件链接到一个共享库中,我可以使用dlopen. .so我需要这样做,因为在加载实际内容之前我必须进行大量设置。

但每次我尝试链接该-shared选项时,都会收到错误 -

创建共享库时不能使用R_X86_64_PC32针对符号的重定位;splay_tree_lookup重新编译-fPIC

我从源代码重新编译没有任何问题。但我不想使用-fPIC. 这是我们正在开发自定义编译器的研究项目的一部分。PIC 不适用于我们试图在编译器中提供的保证类型。

是否有一些我可以使用的标志,ld以便它生成加载时重定位库。事实上,我没有搬家,也没什么问题。我可以为库提供基地址,dlopen如果虚拟地址不可用,则可能会失败。

我用来编译c文件的命令相当于 -

clang -m64 -c foo.c
Run Code Online (Sandbox Code Playgroud)

为了链接我正在使用

clang -m64 -shared *.o -o foo.so
Run Code Online (Sandbox Code Playgroud)

我说等效是因为它是一个自定义编译器(forked off clang)并且有一些额外的步骤。但它是等价的。

c linux linker ld

6
推荐指数
1
解决办法
2399
查看次数

Linux中零页面最快的方法

我需要在Linux中清除大地址范围(一次200页的顺序).我试过两种方法 -

  1. 使用memset- 清除地址范围的最简单方法.执行速度比方法2慢一点.

  2. 使用munmap/ mmap- 我调用munmap了地址范围,然后mmap再次使用相同的权限再次使用相同的地址.自MAP_ANONYMOUS传递以来,页面被清除.

第二种方法使基准测试运行速度提高5-10%.该基准测试不仅仅是清除页面.如果我理解正确,这是因为操作系统有一个零页面池,它映射到地址范围.

但因为我不喜欢这种方式munmap,并mmap没有原子.在某种意义上,另一个mmap(同时使用NULL作为第一个参数)可以使我的地址范围无法使用.

所以我的问题是Linux是否提供了一个系统调用,可以将物理页面换成零页面的地址范围?

我试着看一下glibc的来源(特别是memset),看看他们是否使用任何技术来有效地做到这一点.但我找不到任何东西.

c linux

6
推荐指数
2
解决办法
587
查看次数

结构赋值是否保证填充也相等

假设我有一个包含2个字段的结构和C的实现,我在这些字段之间也有一些填充.

如果我创建结构的两个变量并将它们分配给另一个,那么填充是否会保证相等?

我知道对于大多数编译器来说都是如此(因为它们只调用memcpy),但是我想知道标准中有关填充的指定内容?

这个问题的意图是,我可以memcmp用来检查结构的相等性.

假设我有一个编译器,它发出的代码只是分配结构的所有成员而不是执行memcpy,它是否是struct操作赋值的有效实现?

c struct language-lawyer

5
推荐指数
2
解决办法
198
查看次数

是否允许为 std::array 定义专门化?它会导致未定义的行为吗?

我正在一个有类的图书馆工作foofoo有一个不平凡的构造函数。当我创建std::arrayof foo( std::array<foo, 10>) 时,构造函数被调用 10 次。我想实现一种单独的方式来初始化foo. 定义专业化是否会std::array<foo, N>导致未定义的行为或任何其他问题?如果可以的话,我的专业需要具备哪些属性?

https://en.cppreference.com/w/cpp/language/extending_std表示允许自定义类型的专业化,除非明确禁止,并且https://en.cppreference.com/w/cpp/container/array没有说什么关于它。

c++ stdarray

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

如何在 immutable.js 中合并地图?

我想得到如下地图:

Map{
   "status":1,
    "user":{
        "name":"more",
        "age":8,
        "id":1
    }
}
Run Code Online (Sandbox Code Playgroud)

我的完整代码是:

import {fromJS} from 'immutable'
let b={
    "user":{
         name:"more11",
         age:8
    },
    "status":1
}
let d={
    "id":1,
    "name":"more",
    "age":19
}
let d1=fromJS(d)
let b2=fromJS(b)
Const map2=b1.get('user).mergeDeepIn(d1)
console.log(map2.getIn(['user','name']));
console.log(map2.getIn(['user','age']));
Run Code Online (Sandbox Code Playgroud)

原码图片

javascript reactjs immutable.js

4
推荐指数
1
解决办法
4725
查看次数

为什么使用不在范围UB中的标识符而不是错误

我引用ANSI_ISO + 9899-1990,在所有未定义行为列表中 -

  • 使用在当前范围中不可见的标识符

为什么使用未定义的变量UB而不是错误?我想知道这背后的原因吗?制作UB不正确的一切是否有效?

我知道大多数编译器都将其视为错误.但为什么标准会这样说呢?

或者标准中没有"错误"的概念?c的语法是.*但是它的某些部分有UB?

c c89 undefined-behavior language-lawyer

3
推荐指数
1
解决办法
106
查看次数

指针与空字符合法比较?

比较指向'\0'合法的指针?

关于clang ++的主干版本(25836be2c)

const char *a = "foo";

if(a == '\0')
Run Code Online (Sandbox Code Playgroud)

给出一个错误:指针和整数之间的比较('const char*'和'int')

if(a == 0)
Run Code Online (Sandbox Code Playgroud)

没有按预期给出任何错误.

用于与指针进行比较的空指针是否等效于空指针?这是编译器错误吗?

另一点是,此错误未显示"-std = c ++ 03"标志,但显示"-std = c ++ 11"标志.但是,当我使用g ++(v4.8.5)时,我没有在这两个标准中得到错误

c++

3
推荐指数
1
解决办法
375
查看次数