I'm having troubles when calling a function taking a pointer to a string as a parameter. I need to get an Element's name.
// method
void getStringFromCsv( char ** str );
Let me introduce the structures I'm working with (not written by me and part of a much bigger project, I can't modify them).
// typedefs
typedef char T_CHAR64[64];
typedef T_CHAR64 T_SYMBOL;
// generic element
typedef struct Element
{
T_SYMBOL name;
} T_Element;
// csv element
typedef struct CsvElement
{
Element * pElement;
int id;
} T_csvElement;
So, basically, I thought I would call the function like this :
T_Element * pData; // Not null, filled earlier
getStringFromCsv( &pData->pElement->name );
But this doesn't work (warning: passing argument 1 of ‘STR_toCsv’ from incompatible poi开发者_StackOverflow中文版nter type). I'm using gcc with NetBeans 6.8.
I tried many things...
T_SYMBOL foo = "foo";
T_SYMBOL * pFoo = &foo;
getStringFromCsv( pDef->name, &pFoo ); // error : passing from incompatible pointer type
T_CHAR * pBar = &foo; // error : init from incompatible pointer type
T_CHAR * pBaz = &(foo[0]); // OK
getStringFromCsv( pDef->name, &pBaz ); // OK
T_SYMBOL * pFooTest = &(foo[0]); // error : init from incompatible pointer type
...but ended up casting name to a char ** :
getStringFromCsv( (char**) &pData->pElement->name );
What is wrong with my code ? Basically, SYMBOL = CHAR *, right ? Why is SYMBOL* != CHAR** ? I'm pretty sure I'm missing something simple but right now... Nothing came.
EDIT Here is getStringFromCsv :
void getStringFromCsv( char ** data )
{
// pDesc is defined and not null
csvDescriptorCat( pDesc, *data);
csvDescriptorCat( pDesc, "\t");
}
void csvDescriptorCat( CsvDescriptor * pDesc, char* str)
{
int len;
if( str != NULL)
{
len = strlen(str);
strcpy( &pDesc->line[pDesc->pos], str);
pDesc->pos += len;
}
}
If you wish to pass &pData->pElement->name
to the function, the function must be declared as:
void getStringFromCsv(T_SYMBOL * str);
Alternatively you can use a temporary char *
as Secure offered - but there's not much point in doing this, because any updates to that char *
's value can't be used - the ->name
member can't be modified, as it's an array.
You might as well just declare the function as:
void getStringFromCsv( char * str );
...and call it as:
getStringFromCsv( pData->pElement->name );
(In this case, the function can still change the contents of the ->name
array. What you can't do is to change the position of the array itself).
As well as Secure's option, there's another way if your compiler supports C99 compound literals:
getStringFromCsv( &(char *){ pData->pElement->name } );
name
is an array of chars, so &name gives you a pointer to char[64], as Vicky already answered. But casting makes things worse, because it tells the compiler to treat the first chars of the array as a pointer to the real array.
See the C-FAQ: http://c-faq.com/aryptr/aryptr2.html
I think you can use a temporary char* here:
char *tmp = pData->pElement->name; // array decays to pointer
getStringFromCsv(&tmp);
If this is expected by the function. Expecting a char**
, make sure that it doesn't try to reallocate the memory. For simply filling it, a char*
would be enough.
Alas, one of the little secrets of C that people fail to tell you, an array is not the same thing as a pointer. if x is defined as int x[5] or whatever, &x == x. Try out this code below:
#include <stdio.h>
int main(int argc, const char *argv[])
{
char x [5];
char *y;
printf("%08x\n", x);
printf("%08x\n", &x);
printf("%08x\n", y);
printf("%08x\n", &y);
return 0;
}
Considering this : http://c-faq.com/decl/strlitinit.html
char a[4] = "hello";
char* p = "hello";
Aren't the same thing (even if they seem to be). So my SYMBOL and CHAR* cannot be exchanged, right ?
Is there a workaround, or another solution ?
Yes, under the covers T_SYMBOL is handled like a char *. But you've declared it as a char[64], so you're passing in a pointer to a char[64] not a pointer to a pointer to a char. The compiler is keeping track of that for you.
Personally in this situation I would just cast it as you did at the end of your question.
精彩评论