函数原型中的顶级 volatile 或 limit 是否重要?

M.M*_*M.M 5 c qualifiers language-lawyer restrict-qualifier

以下原型之间有什么实际区别吗?

void f(const int *p);

void f(const int *restrict p);

void f(const int *volatile p);
Run Code Online (Sandbox Code Playgroud)

C11 6.7.6.3/15 节(最后一句)指出,为了确定类型兼容性,不考虑顶级限定符,即允许函数定义在其参数上具有与原型不同的顶级限定符宣言了。

然而(与 C++ 不同)它并没有说它们被完全忽略。在这种情况下,const这显然是没有意义的;volatile然而,在和的情况下restrict也许可能存在差异。

例子:

void f(const int *restrict p);

int main()
{
     int a = 42;
     const int *p = &a;
     f(p);
     return a;
}
Run Code Online (Sandbox Code Playgroud)

原型中的存在是否restrict允许编译器优化afor的读取return a;

相关问题

iva*_*rec 1

如果标准中没有任何内容,则由编译器决定,但似乎至少对于 gcc 4.9(对于 x86)它们被忽略。检查我用来逗弄编译器的这个小片段:

static int b;

void f(const int *p) {
  b = *p + 1;
}

int main()
{
     int a = 42;
     const int *p = &a;
     f(p);
     return a;
}
Run Code Online (Sandbox Code Playgroud)

如果我按原样编译它,我会得到

f(int const*):
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    addl    $1, %eax
    movl    %eax, b(%rip)
    popq    %rbp
    ret
main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    $42, -12(%rbp)
    leaq    -12(%rbp), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    f(int const*)
    movl    -12(%rbp), %eax
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

如果我使用void f(const int *__restrict__ p)编译它,我得到

f(int const*):
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    addl    $1, %eax
    movl    %eax, b(%rip)
    popq    %rbp
    ret
main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    $42, -12(%rbp)
    leaq    -12(%rbp), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    f(int const*)
    movl    -12(%rbp), %eax
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

Anf 最后,如果我使用void f(const int *__volatile__ p)编译它,我得到

f(int const*):
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    addl    $1, %eax
    movl    %eax, b(%rip)
    popq    %rbp
    ret
main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    $42, -12(%rbp)
    leaq    -12(%rbp), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    f(int const*)
    movl    -12(%rbp), %eax
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

所以看起来实际上它们在 C 中也被忽略了。