简体   繁体   English

如何在struct成员数组中应用restrict指针类型关键字?

[英]How to apply the restrict pointer type keyword in struct member arrays?

Say I have a struct defined like so: 假设我有一个像这样定义的struct

typedef struct MyStruct {
    double a[3];
    double b[6];
} MyStruct;

I pass the structures to a function to perform some operations. 我将结构传递给函数以执行某些操作。 For example: 例如:

void MyFcn(MyStruct *out, const MyStruct *in) {
    out->a[2] = in->b[5];
    /* do more stuff */
}

If I want to qualify the array pointers MyStruct.a and MyStruct.b as not having overlapping memory with the restrict keyword, is there any way of doing this? 如果我想要将数组指针MyStruct.aMyStruct.b为没有与restrict关键字重叠的内存,有没有办法做到这一点?

Perhaps most compilers would optimize assuming that MyStruct.a and MyStruct.b point to contiguous memory block without any aliasing anyways, and there's no point in adding the restrict qualifier? 也许大多数编译器都会优化,假设MyStruct.aMyStruct.b指向连续的内存块而没有任何别名,并且添加限制限定符没有意义? I have no idea. 我不知道。

I know I could simply make a and b pointers instead of arrays like so 我知道我可以简单地制作a和b指针而不是像这样的数组

typedef struct MyStruct {
    double *restrict a;
    double *restrict b;
} MyStruct;

but considering the size of the arrays are known, this approach makes it difficult to debug overflows and unnecessarily complicates variable initializations (requires dynamic memory allocations or compound literals and designated initializers). 但是考虑到数组的大小是已知的,这种方法使得调试溢出变得困难并且不必要地使变量初始化变得复杂(需要动态存储器分配或复合文字和指定的初始化器)。

EDIT 编辑

From the comments below, I need to clarify that I intended for the example to better describe the question, not constrain it to that use case. 从下面的评论中,我需要澄清一点,我打算让这个例子更好地描述问题,而不是将其限制在该用例中。 The answers did clarify that struct members cannot have overlapping memory (thats' what unions are for). 答案确实澄清了结构成员不能有重叠的记忆(那就是工会的用途)。

However, the question still remains for different function inputs/outputs. 但是,问题仍然存在于不同的功能输入/输出。 For any number of function inputs/outputs with different struct definitions, would the compiler optimize if there are possibilities of aliased arrays between structs? 对于具有不同结构定义的任意数量的函数输入/输出,编译器是否会优化结构之间是否存在别名数组? If it would not, how to give the restrict keyword? 如果没有,如何给出restrict关键字?

"If I want to qualify the array pointers MyStruct.a and MyStruct.b ...". “如果我想要限定数组指针MyStruct.a和MyStruct.b ......”。 a and b are arrays (for the first typedef), not pointers and definitive no "array pointers" - that would be something like ab是数组(对于第一个typedef),而不是指针和确定没有“数组指针” - 这将是类似的

char a[10];
... &a ....

Also, if they are implicitly converted to a pointer, these cannot alias for the same struct . 此外,如果它们被隐式转换为指针,则它们不能为同一个结构别名。 If you need distinct pointers to them, you can qualify those restrict . 如果您需要指向它们的不同指针,则可以限定这些restrict However, you do not use pointers to these arrays in your example code, so no need. 但是,您不在示例代码中使用指向这些数组的指针,因此不需要。

The only pointers which might alias are in and out . 唯一的指针可能别名是inout This is a matter of intended usage. 这是预期用途的问题。 I would recommend they actually should not, so you might qualify them restrict and - possibly in additionally const if applicable. 我会建议他们实际应该不是这样,所以你可能有资格他们restrict和-可能in另外const (如果适用)。

Btw: only pointer types can be restrict ed and arrays are no pointers, but decay to them for most operations. 顺便说一句:只有指针类型可以被restrict ,数组不是指针,但对于大多数操作都会衰减。

Oh, and: If the sizes of the arrays are fixed, I agree that making the fields pointers is nonsense and just inefficient bloat. 哦,并且:如果数组的大小是固定的,我同意制作字段指针是无意义的,只是低效的膨胀。

out->a and in->b could overlap if out and in both point to different parts of a union that are offset by some amount. out->ain->b可以重叠,如果outin两者都指向一个联合的不同部分,这些部分偏移了一些量。

It's not possible to use restrict on a struct member. 在结构成员上使用restrict是不可能的。 And I would argue that that doesn't make sense anyway. 我认为这无论如何都没有意义。 How will you fulfil that guarantee? 您将如何履行该保证?

It is sufficient to use restrict on your function parameters, which promises that no part of one struct overlaps with the other. 在函数参数上使用restrict就足够了,这可以保证一个结构的任何部分都不会与另一个结构重叠。

NB. NB。 x = y would generate the same code whether or not x and y overlap anyway. 无论xy是否重叠, x = y都会产生相同的代码。

I'm out a limb here having little experience with restrict . 我在这里缺乏restrict经验。 Based on study, this appears to be right. 根据研究,这似乎是正确的。 So making this wiki for all to modify. 所以让这个wiki供所有人修改。


Add restrict to the function parameters (and not the typedef ). 添加restrict到函数参数(而不是typedef )。 By adding restrict to a pointer, the compiler may assume that only that pointer will access/change the data it points to. 通过向指针添加restrict ,编译器可以假定只有该指针才能访问/更改它指向的数据。 This allows for optimizations desired by OP as the pointers do not alias each others data. 这允许OP所需的优化,因为指针不会彼此别名数据。

typedef struct MyStruct {
    double a[3];
    double b[6];
} MyStruct;

void MyFcn(MyStruct * restrict out, const MyStruct *restrict in);

So now MyFcn() can assume in its use of in and out will not point to the same data. 所以现在MyFcn()可以假设在使用inout时不会指向相同的数据。 Calling code should also never do MyFcn(&data, &data) as that breaks the contract as calling code sent pointers to overlapping memory. 调用代码也应该永远不要做MyFcn(&data, &data)因为调用代码发送指向重叠内存的指针会破坏契约。

Some restrict specifications 一些restrict规范

An object that is accessed through a restrict-qualified pointer has a special association with that pointer. 通过限制限定指针访问的对象与该指针具有特殊关联。 This association, ... requires that all accesses to that object use, directly or indirectly, the value of that particular pointer. 此关联,...要求对该对象的所有访问直接或间接使用该特定指针的值。 The intended use of the restrict qualifier ... is to promote optimization, ... C11dr §6.7.3 8 restrict限定符的预期用途是促进优化,...C11dr§6.7.38

Types other than pointer types whose referenced type is an object type shall not be restrict-qualified. 引用类型为对象类型的指针类型以外的类型不应受限制。 §6.7.3 2 §6.7.32

A translator is free to ignore any or all aliasing implications of uses of restrict . 翻译人员可以自由地忽略使用restrict任何或所有别名含义。 §6.7.3.1 6 §6.7.3.16


Even one restrict parameter may make sense. 甚至一个restrict参数也可能有意义。

char buf[100];
void foo1(char * restrict p1) {
  /* foo1() knows p1 does not overlap global `buf`. */
  strcpy(buf, p1);  
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM