【问题标题】:Behaviour of restrict keyword inside structs结构体中限制关键字的行为
【发布时间】:2015-04-13 05:43:19
【问题描述】:

场景:

假设我有一个struct 类型,其中包含一堆指针,所有这些指针都声明为restrict,以及一个将其中的几个struct 作为参数的函数,如下所示:

struct bunch_of_ptr 
{
    double *restrict ptr00;
    double *restrict ptr01;
    ...
    double *restrict ptr19;
}

void evaluate(struct bunch_of_ptr input, struct bunch_of_ptr output) 
{
    // do some calculation on input and return results into output
}

根据http://www.oracle.com/technetwork/server-storage/solaris10/cc-restrict-139391.htmlinput.ptrXXinput.ptrYY 将被视为无锯齿。

问题:

编译器是否也将input.ptrXXoutput.ptrYY 视为非别名?

【问题讨论】:

    标签: c struct c99 restrict-qualifier


    【解决方案1】:

    应该的。对于您在某处声明为restrict 的每个指针,编译器可以假定它是对相应数据的唯一访问。通过声明这些,您实际上为编译器提供了保证。

    是否所有编译器都将利用该信息是另一个问题。通过struct 传递restrict 指针并不是很常见,所以你必须看看你的编译器做了什么。

    【讨论】:

    • 你确定吗?请注意输入和输出是按值传递的,而不是指针
    • @Pandrei:参数对象的成员是restrict -qualified 指针。我不确定确切的语义,但我不认为限定符会被简单地忽略(除了兼容的编译器可以忽略 all restrict 限定符)。
    • @Pandrei, restrict 资格是一件很奇怪的事情。从某种意义上说,它并不限定参数本身,而是限定参数指向的对象。无论struct 是否被复制,该函数都会看到restrict 限定指针。
    • 限制限定符行为在很大程度上取决于编译器,但在这种情况下,我希望输入和输出不被视为仅对每个结构的成员进行非混叠。
    • 如果restrict 指针存储在自动对象中,则该对象的生命周期通常会明确该对象对其所占用的任何存储的所有权的持续时间。如果例如在堆上创建一个包含restrict 指针的结构并在存储被重用于其他目的之前使用一段时间,结构中的指针将保留对象的所有权多长时间?
    【解决方案2】:

    我认为您的代码中存在更大的问题:您将两个结构变量 按值 作为输入传递给函数

    void evaluate(struct bunch_of_ptr input, struct bunch_of_ptr output) 
    

    这样做的效果是结构的每个成员都将被复制到堆栈上;这浪费了很多堆栈空间,并且为此函数带来了很多开销。 此外,编译器将忽略此处的限制限定符,因为该结构不像宏那样扩展,就编译器而言,传入了两个 struct 类型的参数并且没有关于别名的指示。

    这可能是你想要的:

    void evaluate(struct bunch_of_ptr *restrict input, struct bunch_of_ptr *restrict output) 
    

    【讨论】:

    • 我正在使用当前需要大约 40 个指针作为参数的代码。将它们打包成结构并不是为了节省堆栈空间(暂时),只是为了简化调用签名。换句话说,是的,我上面的问题中给出的代码符合预期。
    • 我的回答仍然有效;就编译器而言,每个结构的成员不会重叠,但输入和输出成员可能会重叠。你可以检查生成的asm代码来确认
    猜你喜欢
    • 2012-10-29
    • 2022-01-22
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    相关资源
    最近更新 更多