Message | |
Sign in to post your reply or Sign up for a free account.
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
| last post by: |
By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use .
To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.
Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode .
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
I'm doing polymorphism in C (without ++, it's an embedded target where no C++ compiler is available).
All is working well so far, but when I compile the code with a recent GCC (for the unit tests), I have dozens of incompatible-pointer-types warnings which I'd like to fix (if possible).
The minimal example is as follows:
So in principle the compiler tells me, that I cannot mix void * with Foo * here. Any ideas how to fix this warning?
Thanks and regards
Qt has to stay free or it will die.
@aha_1980 said in Fixing `-Wincompatible-pointer-types` compiler warning :
I'm doing polymorphism in C
That's a new one on me! But never mind, I get the gist.
So you can see why the complaint. Your table demands functions which take a void * parameter but you are trying to set from a function which takes a Foo * .
To fix you must cast the actual function pointers to match the table's formal function definition. Create a convenient typedef TABLEFUNC for the int (*function)(void *) signature and
yes that would work (it is typedef int (*TABLEFUNC)(void *) as definition, but otherwise alright.
The only problem with that: the real table contains about 20 different TABLEFUNC definition, i.e. TABLEFUNC0 , TABLEFUNC1 , ... TABLEFUNC19 ). So a bit of work, but still manageable.
Except someone has an easier hint ;)
@aha_1980 what do you mean with I have dozens of imcompatible-pointer-types warnings which I'd like to fix (if possible)
Don't tell me you're not running with -Werror 😱
I would like to help, but I have no idea, sorry :(
Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct
Q: What's that? A: It's blue light. Q: What does it do? A: It turns blue.
@J-Hilk the embedded compiler does not even complain about that.
And for gcc, I have to fix the ~100 warnings first before enabling such options ;)
You have to cast the pointers explicitly (as @JonB said). Ideally I'd do this with macro-magic, where I declare a table for a class with a macro, I start/end the table definition for a specific structure with a macro and define each of the entries with another. Also I'd do this at init time (just saying).
I have a question, though. Q: Why is the method taking void * , why not take directly an object pointer?
@JonB said in Fixing `-Wincompatible-pointer-types` compiler warning :
That's a new one on me!
C++ didn't invent this idea. It's as old as programming, more or less.
Read and abide by the Qt Code of Conduct
@kshegunov said in Fixing `-Wincompatible-pointer-types` compiler warning :
If you look around, you'll see as many references saying you cannot do polymorphism from C as those which say you can. with cheating-function-pointers :)
The only problem with that: the real table contains about 20 different TABLEFUNC definition, i.e. TABLEFUNC0, TABLEFUNC1, ... TABLEFUNC19). So a bit of work, but still manageable.
I don't understand. The typedef /macro is a single one for the type of the table elements , not the type(s) of the functions (which could vary) you put in it? So if you have one "the real table" I don't see why you want 20 typedefs? EDIT From subsequent posts, here I realise I misunderstood. I thought you had an array of same-typed-function-pointers to which you wanted to assign various different actual functions. Looking carefully that does not correspond at all to the example code you gave, but it did apply to me when I had to do this in C during the last millennium... :)
Since presumably you have just one table initialisation in one place (or maybe it's 20, not sure which), you could #pragma that warning off around the initialisations? Unless you regard that as worse, and do want code which actually passes the warning....
Q: Why is the method taking void *, why not take directly an object pointer?
Because next to the fooTable , there is a barTable and a bazTable , each having its own type.
I don't understand. The typedef/macro is a single one for the type of the table elements, not the type(s) of the functions (which could vary) you put in it? So if you have one "the real table" I don't see why you want 20 typedefs?
The real table looks like this:
So you need to have typedefs for each function prototype. Some might be reuseable, but probably it's better to have one for each row.
Since presumably you have just one table initialisation in one
No, I have a handful implementations of that.
@kshegunov idea of having a macro to create all the tables sounds great, I'll need to try that.
Thanks for your help
Nothing cheating about them. This is what the C++ compiler does under the hood, and it's been known from the "invention" of virtual . It's a concept, it isn't some black magic, and the concept predates the language implementation. Try to use a virtual method in a class constructor and see how well it works before having a fully resolved vptr if you don't believe me.
I don't understand. The typedef /macro is a single one for the type of the table elements , not the type(s) of the functions (which could vary) you put in it? So if you have one "the real table" I don't see why you want 20 typedefs?
Functions may take a different set of arguments, I imagine.
I personally would.
Because next to the fooTable, there is a barTable and a bazTable, each having its own type.
Yeah, I think that's "more correct" approach. Consider:
expanding to something like:
@kshegunov I'll try that tomorrow. Sounds like a clever, reuseable, and clean macro solution :)
and clean macro solution
As much as such a thing exists ;P
@kshegunov It doesn't - But in C it's the only possibility ;)
Yes, sorry, I edited my earlier post, I quite misunderstood and thought you had an array of function pointers to which you wanted to assign.
But now there is something odd in your case. Since you have
that implies you are writing out exactly the required signature for each function pointer in the struct . In which case, why don't they match correctly against the functions you are assigning to them, then you wouldn't need casts...? That is why I was thinking of the array-of-function-pointers situation, where you do have a problem with one array element type and mutiple different function types to assign.
As @kshegunov already wrote, the first pointer, the void * is specialized for each implementation struct - think of inheritance.
So the "base class" has void * and the implementations have Foo * resp. Bar * .
Nothing wrong with that, just that the compiler warns at this point (which is a bit pointless imho, as ever pointer is compatible to void * , but ok.
Nothing wrong with that, just that the compiler warns at this point (which is a bit pointless imho, as ever pointer is compatible to void *, but ok.
Yes, every pointer decays implicitly to void * , but that's not what the compiler whines about. It complains because the function prototypes are different, hence the actual functions may be different, the compiler can't tell out of the box.
What I don't get is: if these classes do not share some base class ( Foo , Bar , or something else), it's a bit hard to think what you're doing in C++ to either of them as a parameter to a function when all they have in common is they are pointers to something unknown?
You don't have to answer/justify yourself. I realise you doubtless know what you are doing and have your own reasons. But that's what strikes me.
What I don't get is: if these classes do not share some base class (Foo, Bar, or something else), it's a bit hard to think what you're doing in C++ to either of them as a parameter to a function when all they have in common is they are pointers to something unknown?
What is a base class in C?
Oh damn! I forgot already this is not C++, sorry... !
OK, well, I still wonder what the shared function does being handed pointers to different C struct s, when you don't know what struct it is...?
Well, as far as I understood the task the point is to allow inheritance support for a language (and a compiler) which doesn't provide it. This entails (if you follow what C++ does) having a static table of methods for each "class". Each "inherited" table then is supposedly referencing the base class' table and further allowing it to be extended. And if you want at the end you can get dynamic polymorphism in. All in all it's not a trivial thing to do, but should be doable with some magic.
Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.
After building I get these warnings: /Users/janhkila/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.c: In function ‘spiTransferBytesNL’: /Users/janhkila/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.c:922:39: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] uint8_t * last_out8 = &result[c_longs-1]; ^ /Users/janhkila/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.c:923:40: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] uint8_t * last_data8 = &last_data;
What can I do to silence this warning?
I tried replacing the contents of this file with the one you linked to as the new one, but the differences are too big (some includes not found and other errors)
If you’re still having issues with this I think I found the relevant changes, I think the line numbers changed since more changes were added to the file. You want these changes: Currently found here
uint8_t * last_out8 = (uint8_t *)&result[c_longs-1]; uint8_t * last_data8 = (uint8_t *)&last_data;
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Get early access and see previews of new features.
I have set up the following struct:
... and then I have defined:
where thread_arr is thread_node_t *thread_arr = NULL;
I don't understand why the compiler is complaining. Maybe I'm misunderstanding something.
Shouldn't struct thread_node_t *next; be struct _thread_node_t *next;
Also, do away with the explicit cast.
It's because thread_arr is a thread_node_t pointer, and your next member is a struct thread_node_t pointer. Not the same thing.
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .
Abstract: Learn how to resolve incompatible pointer type warnings when returning a function pointer in C.
Function pointers are a powerful feature in C that allows functions to be passed as arguments to other functions, or returned as values from functions. However, using function pointers can sometimes result in incompatible pointer type warnings. This article will focus on resolving these warnings when the issue is related to the function return type.
When a function is declared to return a function pointer, the return type must match the type of the function pointer being returned. For example, consider the following code:
The above code will generate a warning because the return type of my\_function is void , but the type of func\_ptr is void(*)(void\*) . The missing void\* parameter in the return type of my\_function is causing the incompatible pointer type warning.
To resolve the incompatible pointer type warning, the return type of the function being assigned to the function pointer must match the type of the function pointer. In the previous example, this can be achieved by modifying the return type of my\_function as follows:
By adding the void\* parameter to the return type of my\_function , the return type now matches the type of func\_ptr , and the warning is resolved.
It is also possible to use function pointers with different parameter types. For example, consider the following code:
The above code will generate a warning because the type of func\_ptr is void(*)(int) , but the return type of my\_function is void(*)(void\*) . To resolve this warning, a cast can be used to convert the return type of my\_function to the type of func\_ptr .
By casting the return type of my\_function to the type of func\_ptr , the warning is resolved.
Incompatible pointer type warnings related to function return types can be resolved by ensuring that the return type of the function being assigned to the function pointer matches the type of the function pointer. If the parameter types of the function and the function pointer do not match, a cast can be used to convert the return type of the function to the type of the function pointer. By understanding these concepts, developers can use function pointers effectively in their C code.
Tags: : C Programming Pointer Warning
Get notified in your email when a new post is published to this blog
June 28th, 2024 2 0
Last time, we wrote a remove_ all_ pointers type trait , but I noted that even though we found a solution, we weren’t finished yet.
We can bring back the one-liner by using a different trick to delay the recursion: Don’t ask for the type until we know we really are recursing.
The sketch is
We first define a type_holder to be a type which has a type member type that holds our answer. If T is a pointer, then the type holder is the recursive call. Otherwise, the type holder is a dummy type whose sole purpose is to have a type member type that produces T again.
We can now pack up that if into a std:: conditional .
It turns out that we don’t need to define a dummy : The C++ standard library comes with one built in! It’s called std:: type_ identity<T> , available starting in C++20. ( We looked at std:: type_ identity<T> a little while ago .)
Now we can inline the type_holder .
Or even better, just derive from the type_holder !
Log in to join the discussion or edit/delete existing comments.
The Aha moment after comparing the initial attempt and the final approach: A manual design of short circuitry.
So basically moving the ::type outside the std::conditional_t fixes it, because this way you don’t construct the template unless it’s necessary. (But the last optimisation is nice.)
Enter the destination URL
Or link to existing content
IMAGES
VIDEO
COMMENTS
5. Here: ptr_one = &x; ptr_two = &x; ptr_three = &y; ptr_one, ptr_two and ptr_three are int* s and &x and &y are double* s. You are trying to assign an int* with a double*. Hence the warning. Fix it by changing the types of the pointers to double* instead of int*, i.e, change the following lines.
1. There is no such type in C as int[][], only the first part of a multidimensional array can be unspecified. So int[][5] is okay. In addition to the other answers posted here, if you can use C99, you can use variable arrays to accomplish what you want: void box_sort(int N, int M, int x[M][N]);
char *q; p = q; // Error: incompatible pointer types. This is because the pointer `p` is of type `int *`, and the pointer `q` is of type `char *`. These two types are incompatible, and you cannot assign a pointer of one type to a variable of another type. An incompatible pointer type is a pointer that is not of the same type as the variable ...
Likewise for the defined types struct, union and enum: two separately defined types are incompatible unless they are defined exactly the same way. However, there are a few cases where different types can be compatible: Every enumeration type is compatible with some integer type. In GNU C, the choice of integer type depends on the largest ...
The warning "assignment from incompatible pointer type" occurs because there is a mismatch in pointer types in the last 3 lines of the function. In the sin_list struct, the "first" and "last" members are declared as pointers to structs of type "node". However, in the function, they are being assigned with "newnode" which is ...
incompatible pointer types passing 'string' (aka 'char *') to parameter of type 'string *' (aka 'char **') Ask Question Asked 3 years, 11 months ago. Modified 2 months ago. Viewed 2k times 0 Im writing a funtion that takes string as a argument and gives back a integer. This function counts lenght of a string entered at the command line argument.
One, the variable that refers to the strcmp function must be one of the type char *, which previously in the course is known as a string, the one you are passing is of type char **, although you do not write it that way but as char * [46]. This type of variables, as you define it, declares an array of pointers (46 in particular), it is pointers ...
Re: gcc complains: assignment from incompatible pointer type. Better yet, eliminate the typedef altogether. typedef should be used to make code clearer, not to avoid typing 'struct' when the code in question needs to know that node is, in fact, a struct. I regret that propriety and the forum rules do not permit me to use more forceful terms in ...
Tour Start here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site
So that they (pointers) would be compatible they shall be pointers to compatible types. 6.7.6.1 Pointer declarators. 2 For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types. However types int or char on the one hand and type void on the other hand are not compatible types.
In function `QuestMenu_BuildListMenuTemplate': src/quests.c:758: warning: assignment from incompatible pointer type. Where line 758 is: gMultiuseListMenuTemplate.itemPrintFunc = QuestMenu_ItemPrintFunc; If you need more information I'd be happy to update the post! Thank you for your time :)
1 10240. Banfa. 9,065 Recognized ExpertModeratorExpert. assignment from incompatible pointer type means that you are assigning a value to a pointer variable from a pointer of a different and incompatible type. In your code that means that p->firstnode and &node are both pointers but the types are not compatible for assignment.
Fixing `-Wincompatible-pointer-types` compiler warning. I'm doing polymorphism in C (without ++, it's an embedded target where no C++ compiler is available). All is working well so far, but when I compile the code with a recent GCC (for the unit tests), I have dozens of incompatible-pointer-types warnings which I'd like to fix (if possible).
It also does implicit conversion of r-value void* to any pointer type, also of equal or stricter CV-qualifier, although it can cause compile warning, and is prohibited in C++. C does not allow implicit conversion of a pointer to void* to a pointer to a pointer of other type, and vice versa. As soon as the result is not void* value, or argument ...
Resolving Incompatible Pointer Types. In ISO C, a pointer to void can be assigned to a pointer of any other type. You do not need to cast the pointer explicitly. C++ allows void pointers to be assigned only to other void pointers. If you use C memory functions that return void pointers (such as malloc(), calloc(), realloc() ), each void pointer ...
Another example is the "& " operator: &sTest is a pointer to a fixed-sized array and has type "const char [5]* "; Both sTest and &sTest point to the same place, but have different types. Thus assigning sTest works because both pointers are of the same type. Assigning &sTest also works, but since the types are different, it generates a warning.
You can try and pass the -Wno-incompatible-pointer-types in the build_flags for a per-project fix. wewowo2125 May 6, 2021, 7:16am 4. I tried replacing the contents of this file with the one you linked to as the new one, but the differences are too big (some includes not found and other errors) supleed2 May 22, 2021 ...
Assignment from incompatible pointer type with structs. 0. Can't assign address of struct to a variable whose type is a typedef of pointer to that struct. 0. Incompatible pointer types assigning to struct. 0. Pointer assignment causing EXC_BAD_ACCESS. 1.
To resolve the incompatible pointer type warning, the return type of the function being assigned to the function pointer must match the type of the function pointer. In the previous example, this can be achieved by modifying the return type of my\_function as follows: void (*func\_ptr)(void\*) = NULL; void my\_function(void\*) {.
We first define a type_holder to be a type which has a type member type that holds our answer. If T is a pointer, then the type holder is the recursive call. Otherwise, the type holder is a dummy type whose sole purpose is to have a type member type that produces T again. We can now pack up that if into a std:: conditional.