Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
400 views
in Technique[技术] by (71.8m points)

c - Is top-level volatile or restrict significant in a function prototype?

Is there any practical difference between the following prototypes?

void f(const int *p);

void f(const int *restrict p);

void f(const int *volatile p);

The section C11 6.7.6.3/15 (final sentence) says that top-level qualifiers are not considered for the purposes of determining type compatibility, i.e. it is permitted for the function definition to have different top-level qualifiers on its parameters than the prototype declaration had.

However (unlike C++) it does not say that they are ignored completely. In the case of const this is clearly moot; however in the case of volatile and restrict maybe there could be a difference.

Example:

void f(const int *restrict p);

int main()
{
     int a = 42;
     const int *p = &a;
     f(p);
     return a;
}

Does the presence of restrict in the prototype allow the compiler to optimize out the read of a for return a; ?

(Related question)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If there is nothing in the standard, then it's up to the compilers, but it seems that at least for gcc 4.9 (for x86) they are ignored. Check this small snippet that I've used to tease the compiler:

static int b;

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

int main()
{
     int a = 42;
     const int *p = &a;
     f(p);
     return a;
}

If I compile it as is, I get

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

If I compile it using void f(const int *__restrict__ p) I get

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

Anf finally if I compile it using void f(const int *__volatile__ p) I get

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

So it seems that in practice they are ignored in C as well.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...