This code is giving me this error, which I don’t understand. I can’t even run the program. Can you help me to fix this error, please? If you don’t understand anything in the code, say it.
error C2040: 'CancelarPedido' : 'ppedido (ppedido)'
differs in levels of indirection from ‘int ()’
printf("nIntroduza opcao:");
scanf("%d",&opc);
switch(opc){
case 1: lista = NovoPedido(lista);break;
case 2: lista = CancelarPedido(lista);break;
case 3: printf("Falta implementar a funcao.");break;
case 4: printf("Falta implementar a funcao.");break;
}
}while(opc!=5);
return lista;
}
ppedido CancelarPedido(ppedido lista)
{
ppedido actual, anterior = NULL;
char id[5];
actual = lista;
if(lista == NULL)
printf("nNao ha pedidos na fila de espera...");
else
{
printf("nIntroduza o ID do pedido que pretende cancelar: ");
scanf("%s", id);
while(actual != NULL && ((strcmp(actual->id, id)) != 0)){
anterior = actual;
actual = actual->prox;
}
if(actual == NULL){
printf("nERRO - Nao existe nenhum pedido com o ID introduzido.");
return lista;
}
if(anterior == NULL){
lista = actual->prox;
printf("nPedido cancelado com sucesso...");
}
else{
anterior->prox = actual->prox;
printf("nPedido cancelado com sucesso...");
}
free(actual);
return lista;
}
}
Jongware
22.1k8 gold badges52 silver badges100 bronze badges
asked Jun 23, 2012 at 4:23
8
You are calling CancelarPedido before you declared it. You need to reorder the code or add a forward declaration for CancelarPedido.
Without a declaration of CancelarPedido in scope, it defaults to int CancelarPedido(). You get the error message because lista is declared to be a pointer but CancelarPedido is declared to return an int.
answered Jun 23, 2012 at 4:32
Jim BalterJim Balter
16.1k3 gold badges43 silver badges66 bronze badges
4
-
09-10-2001
#1
the Corvetter
Levels of Indirection???
Every once in a while, I get this same warning message that causes DOS to crash and I don’t know what to do about it. I’ll give you the code, and then the warning:
Code:
#include <stdio.h> char vName[] = "John Smith"; char *const pName = &vName; char vDate[] = "9/10/01"; const char *pDate = &vDate; int main() { printf("Name = %s Date = %s", *pName, *pDate); *pName = "George Washington"; pDate = "6/10/01"; printf("Name = %s Date = %s", *pName, *pDate); return (0); }
That’s the code. And the warning message is «‘const char *’ differes in levels of indirection». What exactly would a level of indirection be? Well, this warning is causing the program to crash and it is getting to me. Thanks.
-
09-10-2001
#2
and the hat of int overfl
Well there are quite a few broken indirections in your code.
Code:
char vName[] = "John Smith"; char *const pName = vName; // this is a constant pointer char vDate[] = "9/10/01"; const char *pDate = vDate; // this is a pointer to a constant int main() { printf("Name = %s Date = %s", pName, pDate); pName = "George Washington"; // it's constant, so this assignment is illegal pDate = "6/10/01"; printf("Name = %s Date = %s", pName, pDate); return (0); }
> What exactly would a level of indirection be?
It’s a count of how many *’s you have to go through to get to the real data.> Well, this warning is causing the program to crash and it is getting to me.
Fix the code then — this is one of the warnings you shouldn’t be ignoring.
-
09-10-2001
#3
the Corvetter
Well, I have just gotten a reply from another C message board and I think you two have different explanations. He said that I was trying set set a string to a pointer. The array of a pointer, he said, is memory so you can’t set an array of characters to it. He said that I would have to do the strcopy function to put another string into it. Do you agree? I don’t really understand what you are saying.
When you say the level of indirection is «a count of how many *’s you have to go through to get to the real data», what do you mean? Thanks.
-
09-10-2001
#4
the Corvetter
I think I just realized something. When you say the number of *’s to get to the data, you mean the number of pointers, right? So, where was my error? I read that I can change the pointer to a constant string (for example) and that isn’t working with the string, but the constant. Now that I think of it, it doesn’t really make sense.
Take a look at my first post. So, you’re saying if you have:
Code:
const char *pPointer = &vVar;
that I can’t change either the pointer (pPointer = ‘A’) or I can’t change what it points to (*pPointer = ‘A’)? Is there a difference between my two examples (pPointer = ‘A’ and *pPointer = ‘A’)? But if I have this:
Code:
char *const pPointer = &vVar;
then I can legally do the changes (pPointer = ‘A’ and *pPointer = ‘A’) because the const pointer only means that that pointer can only point to that char address, right? Thanks.
-
09-11-2001
#5
and the hat of int overfl
char vName[] = «John Smith»;
char *pPointer = &vName;Ignoring the const for a moment, this code has incompatible types.
An array name by itself (vName) has the same type as a pointer to any element of the array (&vName[x]), and specifically the same value as a pointer to the first element of the array (&vName[0]).
So you would have
char vName[] = «John Smith»;
char *pPointer = vName;The &vName is a pointer to the whole array, not a pointer to the first element (it’s likely to be the same value as a pointer to the first element, but the type is totally different)
To make this valid, you need a different type of pointer
char hello[] = «hello»;
char (*arr)[6] = &hello;
Note that this isn’t an array of 6 pointers to char, its a pointer (singular) to an array of 6 characters.The const keyword can be used as follows
char hello[] = «hello»;
char world[] = «world»
const char *a = hello;
char * const b = hello;a is a pointer to a constant char — this means you can modify a (say a=world), but you can’t modify what a points to (say a[0] = ‘f’ would be illegal).
b is a constant pointer to char — this means you cannot change b, but you can change b[0]
const char * const c = hello;
means you cannot modify c or c[0]> Do you agree?
No — what you are trying to do is perfectly valid, once you’ve sorted out some of the use of & and * in a place or two.
-
09-11-2001
#6
the Corvetter
So, how come that my code was invalid? I had right syntax (I think). I had this:
Code:
char first[10]; const char *ptrfirst = &first; char last[10]; char *const ptrlast = &last; int main() { ptrfirst = "Thomas"; /* Is this legal? I'm changing the pointer, not the object it points to, right? */ *ptrlast = "Jefferson"; /* Is this legal? I'm changing the object that the pointer points to, not the pointer, right? return (0); }
Isn’t this code right? If not, why? Thanks!
-
09-11-2001
#7
and the hat of int overfl
> const char *ptrfirst = &first;
Recall my previous post about the difference between first and &first.
The levels of indirection are the same, but the pointers are of an incompatible type
So
const char *ptrfirst = first;> ptrfirst = «Thomas»;
Nothing wrong here — ptrfirst is a (variable) pointer to a const char, so assigning the pointer to point to another char is valid.
«string» has the type const char *
So you have these types in the assignment.
const char * = const char *
so all is well> *ptrlast = «Jefferson»;
I get this — warning: assignment makes integer from pointer without a cast
What you’re trying to do here is take a pointer (to the string), cast it to an integer and truncate it so it fits inside a single character.
You have these types in the assignment.
char = const char *
a char just being a small integerIf you tried this
> ptrlast = «Jefferson»;
I get this — warning: assignment of read-only variable `ptrlast’
Althought the types match, you’ve said that ptrlast is a constant, so it complains when you try and modify the pointer.To update this, you would need something like
strcpy( ptrlast, «Jefferson» );
Joined: 21 Jan 2010
Posts: 13
Different levels of indirection | ||||
Posted: Wed Sep 28, 2016 4:50 am | ||||
|
||||
Hi all,
After some time not working with PICs I tried to make a new program for an older project. But I keep running into this error. In my project I want to pass a struct to a function. No problem there but once I make an array of structs and try to loop over each I’m stuck with the error. Of course my project is a bit bigger (but I wouldn’t call it big) but I made a small example which gives the same error.
And to be complete, full error message:
Is it really not possible to loop over array items and pass them by reference to a function That would really break all possibility of scaling a program Or has anyone an alternative? Timo |
Joined: 20 Jul 2010
Posts: 1281
Posted: Wed Sep 28, 2016 6:52 am | ||||
|
||||
Keep in mind that reference parameters are not a C construct but a C++ one and used as an extension to CCS C. They don’t necessarily follow the rules of C++ since they are merely an extension.
This issue is that CCS uses reference parameters to pass *known at compile time* addresses through a function (and as a side effect it normally inlines that function as well). myStructs[i] cannot have a known compile time address since i is not a compile time constant and changes at runtime. That’s why it thinks there are different levels of indirection (a bit of a loose definition IMO, but it is what it is). To do what you want to do, you need to pass the parameter as a pointer:
and call it like:
|
Joined: 11 Mar 2010
Posts: 18356
Posted: Wed Sep 28, 2016 7:00 am | ||||
|
||||
It’s perfectly possible.
You are having a problem because of C shortcuts, and getting misled about what they can do. myStructs[n], is a structure of type _myStruct, not a pointer to such a structure. That is why you can access an element in such a reference directly. myStructs, is a shortcut to the address of the array. This is only described in K&R, to work directly with the array name, not with a ‘sub element’ of the array. CCS happens to automatically treat a fixed index to such a sub element in the same way, but not with a variable, and it is honestly a little bit dangerous was to work. So:
Honestly, I’d only use the array name «on it’s own» as the shortcut, and if wanting to pass the address of an element, always use the ‘&’. Safer, and avoids differences between C versions. The other way is to use the offset in a different way:
This is because ‘myStructs’ is the address of the first element, and if you add to such a pointer, you automatically increment in ‘element sized’ lumps, so ‘myStructs_+i’, is defined as the address of element ‘i’ in the array. The fact you are using reference parameters in the target function, does not really affect things. It still expects to receive an address, it is just that it then ‘works back’ and works on the source variable, not the copy in the function. For a structure, why not just use the reference access mode (using -> instead of ‘.’ to access the sub variable)?. I see Temtronic has said this as well. It is a much safer way of working…. |
Joined: 21 Jan 2010
Posts: 13
Posted: Wed Sep 28, 2016 8:21 am | |
|
|
First of all, thanks guys!
I’m indeed more of a C++ guy I started with PIC but moved to AVR (or ARM now) because of the open tool chains. But this is still an old project I want to revise which means, reprogramming the PIC. But you say this can’t be done by reference in CCS C? I did it by reference instead of pointer because I think it just looks cleaner to call something like myFunction(instance) then to have to add the address operator. In the past I have used this code (button debounce with passing by reference) multiple times without a problem but always on a single button. And I could make multiple structs insteads of an array of structs but that would make looping over them harder (aka, harder to scale). But if by pointer will work fine I will just use that. And about the operator, what is the difference between ‘.’ and ‘->’ as an operator? |
Joined: 11 Mar 2010
Posts: 18356
Posted: Wed Sep 28, 2016 8:37 am | ||
|
||
Three different versions:
By pointer. By reference pointer. By reference. By reference, is not a C ability. CCS offers it, but with limited abilities. Has to be directly ‘to’ a variable. By pointer — standard. By reference pointer, is for things like structures. On this you can pass a pointer ‘to’ a function, but then use it inside the function without having to de-reference it, to operate directly on the original variable. It is to do exactly what you are trying to do. So:
|
Joined: 20 Jul 2010
Posts: 1281
Posted: Wed Sep 28, 2016 9:00 am | ||||||||
|
||||||||
‘.’ is element/member selector and is used directly on structs:
‘->’ is a dereference pointer and select element/membor. This is used with pointers to structs:
alternate syntax to the ‘->’ is:
but I guess they decided that was too messy and added the arrow operator instead. |
Joined: 21 Jan 2010
Posts: 13
Posted: Wed Sep 28, 2016 10:24 am | ||||||||
|
||||||||
Thanks for explaining guys!
Alright, I tried to change my small library to use pass by pointers instead of pass by reference. So I change all the references to pointer (from &b to *b) and all the member operators to dereference member operators (brom b. to b->). And in my code I added the address of operator in front of struc variable names. And tada, it broke it So my library to debounce buttons, and yes, it’s heavily inspired by Arduino With pass by reference.
Test code:
Works like a charm, leds on both outputs turn on. One via debounce. So after changing it: library
Test code:
I would think it should still do the same but only the direct controlled output turns on :/ What am I missing? |
Joined: 11 Mar 2010
Posts: 18356
Joined: 21 Jan 2010
Posts: 13
Posted: Wed Sep 28, 2016 12:49 pm | |
|
|
Why is it a int16? It’s just defined as a macro. And on a PIC16F648A/628A it’s a number between 40 and 55. This might be different for other PICs but at least for the 16F648A I don’t see a problem. We can assign that to an int8 just fine.
And just to check I’m not to stubborn I changed the variable for the pin in the struct, attach-function and in the test code to int16 but that didn’t change a thing. |
Joined: 11 Mar 2010
Posts: 18356
Posted: Wed Sep 28, 2016 1:18 pm | |
|
|
Fair enough. I haven’t used a chip where it is an int8 for ages.
It’s actually the register number*8, plus the bit number. It has to be an int16, if any pin on the chip requires an int16. That does look as if it should work. Why do you waste storage declaring the pin numbers?. Just use #defines for these. |
Joined: 21 Jan 2010
Posts: 13
Posted: Wed Sep 28, 2016 1:33 pm | |
|
|
Like I said, old project, good old 16F628A (/648A)
And yeah, I thought it would be something like that. Didn’t dive into it So yeah, for compatibility it should be int16 but for the 16F648A int8 isn’t the problem. And I’m «wasting memory» because this makes it easy to put pin numbers into an array and just loop over them. Great for scaling things. But because they are const they should not waste memory because they are located in ROM. At least, that seems to be the default if I understand the help of #DEVICE correctly… And last but not least, the passed by reference version works fine, the passed by pointer does not |
Joined: 11 Mar 2010
Posts: 18356
Posted: Wed Sep 28, 2016 3:05 pm | |
|
|
Making them into const, wastes a surprising amount of memory…..
Problem is there has to be code to read them. If you use a #define, the number is written directly inside the code at compile time. A variable, still has to be read. Critical question now comes. What compiler version number are you using?. Problems with things like pointers (and references etc..), are typical for some of the older compiler versions. What version are you on?. |
Joined: 21 Jan 2010
Posts: 13
Posted: Wed Sep 28, 2016 4:08 pm | |
|
|
Mm, true, but the fact it’s scaleable is worth it
I’m using 5.008, on old Uni license…. It’s a bug there? :/ |
Joined: 20 Jul 2010
Posts: 1281
Posted: Thu Sep 29, 2016 6:33 am | ||
|
||
Can’t tell if it is a bug or not, but it appears to be with your use of int1’s. If I change all the int1 variables in the struct and in buttonUpdate to unsigned int8’s I get it to work.
I also changed lastMillis to be unsigned (it is an unsigned value, not a signed value, so the variable should match).
I am compiling with 5.061 and using a PIC24FJ64GA004 since I don’t have any 8 bit chips lying around. You might send an email to CCS support with both files and see what they say about it. |
Joined: 21 Jan 2010
Posts: 13
Posted: Fri Sep 30, 2016 7:29 am | |
|
|
Thanks for testing! I will give it a try once I’m back home. Did not bring my PicKit 2 with me.
I first wanted to say a int1 is just defined as a int8 but then I saw that’s only the case if the compiler isn’t PCM. So int1 is a build in type. I did not specify the unsigned type because the CCS Help says «Unsigned: Data is always positive. This is the default data type if not specified.». But I agree it’s nicer to specify it specifically. And because how a pin number is build up, isn’t that a unsigned as well? (Not that it matters because of the unsigned as default type.) I will also send an email. Because it’s indeed a bit strange it does work with a int8. For now I’ll just use a int8 to do it, project is small and I can handle the extra memory. But I think I’ll change the library to use one byte for all the states (different bits in the same byte) to same some. But thanks again or helping! |
Display posts from previous:
- Remove From My Forums
-
Question
-
hello ,
i’m writing a B+tree implementation in C . using visual studios 2008
i built 2 header files to help me with some functionality,
one is called linked.h witch holds function and structs witch implement a stack using linked list ( for tree traversel , the other is called nodewraper.h , it holds a struct for node ( of a B+tree ) and another struct called node_wraper witch encapsulates
the node and the current visited pointer number (index)all the above is irrelevant , and is just written for thous people who just have to know what i’m trying to do .
i believe in focusing the problem :
iv’e underlined the error below in the code , this is the header file nodewraper.h ,
the error returns twice in make_leaf and make_node , i cant figure out its origin .
iv’e tried replacing node* with void* to imply a general type but i got the same error as before only with void* instead of node*#include<linked.h> #include<stdlib.h> #define order 5 typedef struct node { void ** pointers; int * keys; struct node * parent; int is_leaf; int num_keys; struct node * next; } node; typedef struct { node* _node ; int visited ; }node_wraper; void Init(node** root) { (*root) = make_leaf(); (*root)->parent = NULL; return root; } node* make_leaf() { // here i get an error : : 'make_leaf' : 'node*()' //differs in levels of indirection from 'int ()' node* leaf = make_node(); leaf->is_leaf = 1; return leaf; } // end make_leaf node* make_node() { // here i get an error : error C2040 : 'make_node' : 'node*()' //differs in levels of indirection from 'int ()' node* new_node; new_node =(node*)malloc(sizeof(node)); if (new_node == NULL) { perror("Node creation."); exit(EXIT_FAILURE); } new_node->keys =(int*) malloc( (order - 1) * sizeof(int) ); if (new_node->keys == NULL) { perror("New node keys array."); exit(EXIT_FAILURE); } new_node->pointers =(node**)malloc( order * sizeof(node*) ); if (new_node->pointers == NULL) { perror("New node pointers array."); exit(EXIT_FAILURE); } new_node->is_leaf = 0; new_node->num_keys = 0; new_node->parent = NULL; new_node->next = NULL; return new_node; } // end make node
Answers
-
On 6/22/2011 8:17 PM, eranotz50 wrote:
void Init(node** root)
{ (*root) = make_leaf();You are calling a function without declaring it first. In C++, this is illegal. But the C compiler accepts it and synthesizes a declaration for you — like this:
int make_leaf();
node* make_leaf()
{ // here i get an error : : ‘make_leaf’ : ‘node*()’
//differs in levels of indirection from ‘int ()’And here the compiler complains that the function signature differs from the one it synthesized earlier.
Bottom line — declare names before using them.
Igor Tandetnik
-
Marked as answer by
Thursday, June 23, 2011 1:26 AM
-
Marked as answer by
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS
Contact US
Thanks. We have received your request and will respond promptly.
Log In
Come Join Us!
Are you a
Computer / IT professional?
Join Tek-Tips Forums!
- Talk With Other Members
- Be Notified Of Responses
To Your Posts - Keyword Search
- One-Click Access To Your
Favorite Forums - Automated Signatures
On Your Posts - Best Of All, It’s Free!
*Tek-Tips’s functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.
Posting Guidelines
Promoting, selling, recruiting, coursework and thesis posting is forbidden.
Students Click Here
compiler error «Different levels of indirection»compiler error «Different levels of indirection»(OP) 12 Mar 02 12:23 Could somebody please explain what this message means? I have looked at the microsoft site, but it has helped little. James Goodman Red Flag SubmittedThank you for helping keep Tek-Tips Forums free from inappropriate posts. |
Join Tek-Tips® Today!
Join your peers on the Internet’s largest technical computer professional community.
It’s easy to join and it’s free.
Here’s Why Members Love Tek-Tips Forums:
- Talk To Other Members
- Notification Of Responses To Questions
- Favorite Forums One Click Access
- Keyword Search Of All Posts, And More…
Register now while it’s still free!
Already a member? Close this window and log in.
Join Us Close