最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Why does this function pointer typedef behave differently when used with const? - Stack Overflow

programmeradmin4浏览0评论
#include <stdio.h>

typedef int (*func_t)(int);

int foo(int x) {
    return x * 2;
}



int main() {
    const func_t ptr = foo; // Works
    //const func_t *ptr = &foo; // Fails: why?
    printf("%d\n", ptr(5)); // Outputs 10
}

Issue:

The line const func_t ptr = foo; works fine.

However, uncommenting const func_t *ptr = &foo; results in a compilation error

error: invalid conversion from 'int (*)(int)' to 'const func_t*' {aka 'int (* const)(int)'}

Why does const func_t *ptr = &foo; fail, and how can I fix it?

#include <stdio.h>

typedef int (*func_t)(int);

int foo(int x) {
    return x * 2;
}



int main() {
    const func_t ptr = foo; // Works
    //const func_t *ptr = &foo; // Fails: why?
    printf("%d\n", ptr(5)); // Outputs 10
}

Issue:

The line const func_t ptr = foo; works fine.

However, uncommenting const func_t *ptr = &foo; results in a compilation error

error: invalid conversion from 'int (*)(int)' to 'const func_t*' {aka 'int (* const)(int)'}

Why does const func_t *ptr = &foo; fail, and how can I fix it?

Share Improve this question asked Mar 17 at 8:16 Alphin ThomasAlphin Thomas 1 4
  • 2 It’s not the const that causes the trouble; it's the extra layer of pointer, plus the fact that &function produces the same value as just function. – Jonathan Leffler Commented Mar 17 at 8:20
  • 1 What compiler is that? If there are no copy-and-paste error in the error message it is highly misleading, because it should have said aka 'int (* const*)(int). "How can I fix it?" This depends on what you want to do, especially why you want a pointer to a function pointer, which is not something that commonly needed. – Weijun Zhou Commented Mar 17 at 8:26
  • const func_t *ptr = &foo; is valid in C, but its behavior may vary depending on the compiler implementation and settings. My compiler (gcc 13.2.0, clang 17.0.6, target x86_64-unknown-linux-gnu ) gives incompatible pointer type warning but still compiles. – xy3333 Commented Mar 17 at 9:04
  • 1 @xy3333 Not really. const func_t* is an object pointer type, but &foo is a function pointer type. The C standard does not say you can convert between these two. In fact they may not even be of the same size. See stackoverflow/a/4810460/3966456 – Weijun Zhou Commented Mar 17 at 9:06
Add a comment  | 

1 Answer 1

Reset to default 2

This is one of the reasons why hiding pointers behind typedef isn't a good idea.

const func_t ptr makes the function pointer "const". That is, it is equivalent to int (* const func_t)(int);.

Functions, whenever used in expressions, "decay" into a pointer to that function. That's why ptr = foo; works, foo decays into an int (*)(int). However, just like when dealing with arrays, decay does not happen in case of &. So &foo gives a pointer to a function too.

And you cannot assign an int (*)(int) to a pointer-to-pointer to function and const has nothing to do with that - it's simply the wrong number of redirections.

You could however do this:

const func_t  ptr1 = foo;
const func_t* ptr2 = &ptr1;

ptr2 is int (*const *)(int) and that's what you get if you take &ptr1.

Best practice here is to get rid of the hidden pointer inside the typedef in the first place, since it is obviously quite confusing:

typedef int func_t (int);
...
func_t* const ptr1 = foo;
发布评论

评论列表(0)

  1. 暂无评论