compiler won't allow dimensioned array of Char* to be signed to another???

G

Gregg Woodcock

My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

What am I missing? How can this be done?
 
A

Andrey Tarasevich

Gregg said:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

Declaration of an array of unknown size will only accept an aggregate
initializer (i.e. '{}'-enclosed initializer). The one you provided is not.
What am I missing? How can this be done?

What exactly are you trying to do?
 
C

Charlie Gordon

Gregg Woodcock said:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:

You could have explained what you intended in this code, I will try and guess
for now...
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};

You should use const char * here because these arrays hold pointers to constant
string literals.
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!

Try this : char **arrayCharPtrVar = someBoolean ? arrayCharPtr1 : arrayCharPtr2;
Use const char **... if you followed my advice above.
StrCopy(someString, arrayCharPtr[0]);

StrCopy is not strcpy, what in hell can it do that strcpy can't ?
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

The problem was with the type itself : you should declare a pointer, not an
agregate.
What am I missing? How can this be done?

Like I say.
 
G

Gregg Woodcock

Andrey Tarasevich said:
Gregg said:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

Declaration of an array of unknown size will only accept an aggregate
initializer (i.e. '{}'-enclosed initializer). The one you provided is not.
What am I missing? How can this be done?

What exactly are you trying to do?

You do a pretty good compiler immitation: perfectly accurate and
totally worthless.
I *KNOW* I cannot do what I want to do the way I am trying to do it
(the compiler is quite clear about that); That's why I gave the
complete context showing WHAT I want to do. I can hardly be more
clear.

I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...
 
O

Old Wolf

My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I think you want:
char **arrayCharPtrVar =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2);

which will give you a pointer to the first element of either
array 1 or array 2.

If you have:
char *arrayCharPtrVar[]
then you are declaring another array (separate from the 2 existing
arrays). The best you can hope for here would be to have a copy
of one of your 2 arrays (giving you 3 arrays in total). If that's
what you want, then you can't do it with initializer syntax; you
will have to declare the array and then memcpy it from one of the
other two.

Incidentally, these should be: const char *arrayCharPtr1[] etc.
You can't modify a string literal, even though the language
allows you to assign them to a "char *" without warning.
So it is best to use "const" so that you will get a warning
if you try and modify one.
I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

'&a[0]' is identical to just 'a' , when used in an expression
(except for: sizeof(X) or &X or X++ etc.)
 
G

Gregg Woodcock

Charlie Gordon said:
Gregg Woodcock said:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:

You could have explained what you intended in this code, I will try and guess
for now...
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};

You should use const char * here because
arrays hold pointers to constant string literals.

Normally I'd agree but I am programming for Palm (that explains the
StrCopy instead of strcopy which are essentially the same) and on the
Palm, declaring something as const causes the compiler to put it into
the local static code segment which, if it is not code segment #0 (in
my case it will not be) means it cannot be accessed by any other code
segment (which I require). This is certainly one good way to make it
unwritable!
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!

Try this : char **arrayCharPtrVar = someBoolean ? arrayCharPtr1 : arrayCharPtr2;
Use const char **... if you followed my advice above.

I should have mentioned I tried this too and it was not acceptible to
the compiler. However I just realized my mistake: I was compiling
pedantic and this was not an error but a WARNING! When I realized
this, I fixed it right away by casting like this:

char **arrayCharPtrVar =
((someBoolean) ? (char **)arrayCharPtr1 : (char **)arrayCharPtr2);

Thank you for your help!
 
C

CBFalconer

Gregg said:
Andrey Tarasevich said:
Gregg Woodcock wrote:
My compiler (m68k-gcc) does not allow this (simplified example;
not my real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should
work, too; it doesn't.

Declaration of an array of unknown size will only accept an
aggregate initializer (i.e. '{}'-enclosed initializer). The one
you provided is not.
What am I missing? How can this be done?

What exactly are you trying to do?

You do a pretty good compiler immitation: perfectly accurate and
totally worthless.
I *KNOW* I cannot do what I want to do the way I am trying to do it
(the compiler is quite clear about that); That's why I gave the
complete context showing WHAT I want to do. I can hardly be more
clear.

I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...

You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.
 
F

Flash Gordon

On 1 Dec 2004 19:32:13 -0800
Charlie Gordon said:
Gregg Woodcock said:
My compiler (m68k-gcc) does not allow this (simplified example;
not my real code) and I don't see why not:

You could have explained what you intended in this code, I will try
and guess for now...
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};

You should use const char * here because
arrays hold pointers to constant string literals.

Normally I'd agree but I am programming for Palm (that explains the
StrCopy instead of strcopy which are essentially the same) and on the
Palm, declaring something as const causes the compiler to put it into
the local static code segment which, if it is not code segment #0 (in
my case it will not be) means it cannot be accessed by any other code
segment (which I require). This is certainly one good way to make it
unwritable!

As long as you are only accessing it for reading!
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error
here!

Try this : char **arrayCharPtrVar = someBoolean ? arrayCharPtr1 :
arrayCharPtr2; Use const char **... if you followed my advice above.

I should have mentioned I tried this too and it was not acceptible to
the compiler. However I just realized my mistake: I was compiling
pedantic and this was not an error but a WARNING! When I realized
this, I fixed it right away by casting like this:

char **arrayCharPtrVar =
((someBoolean) ? (char **)arrayCharPtr1 : (char **)arrayCharPtr2);

The warning doesn't meen you need a cast, it meens the variable is of
the wrong type somewhere, either that or the compiler is broken or you
are not doine what you show.

markg@brenda ~ $ cat t.c
#include <stdlib.h>

int main(int argc, char *argv[])
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
int someBoolean = 0;
char **arrayCharVarPtr =
(someBoolean) ? arrayCharPtr1 : arrayCharPtr2;
return 0;
}
markg@brenda ~ $ gcc t.c -ansi -pedantic -Wall -O
t.c: In function `main':
t.c:8: warning: unused variable `arrayCharVarPtr'
markg@brenda ~ $

Not that gcc defines what is acceptable, but it is pretty good about
complaining about producing required diagnostics for incompatible
pointer types.

I *strongly* suggest you try running the above code as is through your
compiler with the pedantic switch and if it compiles OK go back to your
code and see what you have done differently.
 
O

Old Wolf

char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};

You should use const char * here because
arrays hold pointers to constant string literals.

Normally I'd agree but I am programming for Palm and on the
Palm, declaring something as const causes the compiler to put it into
the local static code segment which, if it is not code segment #0 (in
my case it will not be) means it cannot be accessed by any other code
segment (which I require). This is certainly one good way to make it
unwritable!

The 'const' refers to the chars, not to the array of them.
The array will be in your modifiable data space, regardless
of whether the chars are const or not.
Where the compiler places string literals is also independent
of how you refer to them later. You can control this with a
linker switch, if at all.
I expect you will find that changing "char *" to "const char *"
won't affect where in memory anything gets put (try it and see).
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!

I should have mentioned I tried this too and it was not acceptible to
the compiler. However I just realized my mistake: I was compiling
pedantic and this was not an error but a WARNING! When I realized
this, I fixed it right away by casting like this:

char **arrayCharPtrVar =
((someBoolean) ? (char **)arrayCharPtr1 : (char **)arrayCharPtr2);

Can you say what the error message was? The type of "arrayCharPtr1"
in an expression is already "char **", so either your compiler
is awful, you didn't post the exact code, or there is some other
condition (possibly related to the code segments you mentioned)
that you are shutting up by doing the cast but would cause a
runtime error.
 
C

Charlie Gordon

CBFalconer said:
Gregg Woodcock wrote:
I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...

You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.

nonsense!

char **arrayCharPtrVar;
 
C

CBFalconer

Charlie said:
CBFalconer said:
Gregg Woodcock wrote:
I have to arrays of strings.
I want to assign one or the other array to a variable such that I can
index any string in the array with something like var[index].
It is very simple and I am quite sure not impossible...

You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.

nonsense!

char **arrayCharPtrVar;

Why do you want a pointer to (a pointer to a char)?

If it is not clear draw yourself some box diagrams, showing what
points where. The only initialized elements are the original
arrays of pointers.
 
A

Alex Fraser

CBFalconer said:
Why do you want a pointer to (a pointer to a char)?

Because "the address of a location holding a char *" has type char **, and
the "final result needs to be of this type".

Alex
 
A

Al Bowers

Gregg said:
My compiler (m68k-gcc) does not allow this (simplified example; not my
real code) and I don't see why not:
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[] =
((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here!
StrCopy(someString, arrayCharPtr[0]);
}

I have also tried "= &arrayCharPtr1[0]" which I assumed should work,
too; it doesn't.

What am I missing? How can this be done?

In the initialization of arrayCharPtrVar, you are not providing values
appropriate for the entity being initialized.

You can use function memcpy.

#include <stdio.h>
#include <string.h>

int main(void)
{
char *arrayCharPtr1[] = {"a", "ab", NULL};
char *arrayCharPtr2[] = {"A", "AB", NULL};
char *arrayCharPtrVar[3];
int b , i;

for(b = 0; b < 2; b++)
{
memcpy(arrayCharPtrVar,b?arrayCharPtr2:arrayCharPtr1,
sizeof arrayCharPtrVar);
printf("b = %d\n",b);
for(i = 0; i < 3; i++)
if(arrayCharPtrVar)
printf("arrayCharPtrVar[%d] = \"%s\"\n",
i,arrayCharPtrVar);
putchar('\n');
}
return 0;
}
 
C

CBFalconer

Alex said:
Because "the address of a location holding a char *" has type char **,
and the "final result needs to be of this type".

No you don't. If you have

int x;

and you want to place a value into that location, you simply write
"x = value;". There is no need whatsoever to take the address of
x. Same thing.

char *p;

p = somepointer;
 
A

Alex Fraser

CBFalconer said:
Alex said:
Because "the address of a location holding a char *" has type char **,
and the "final result needs to be of this type".

No you don't. [...]

Sorry, but you do. The words in your first post were correct, but the code
was not.

char *array1[] = {"one", "two", 0};
char *array2[] = {"three", "four", 0};
char **p = condition() ? array1 : array2;

Alex
 
J

Joe Wright

CBFalconer said:
Alex said:
CBFalconer said:
Charlie Gordon wrote:

[snip]

You have successfully formed your arrays of pointers to strings, so
your only purpose is to select one for future use. Think about how
those arrays are represented: they are passed as a pointer to the
first element, i.e. as the address of a location holding a char *.

Your final result needs to be of this type, not of an array of
pointers. So declare it as such:

char *arrayCharPtrVar;

and follow up with code to initialize it.

nonsense!

char **arrayCharPtrVar;

Why do you want a pointer to (a pointer to a char)?

Because "the address of a location holding a char *" has type char **,
and the "final result needs to be of this type".


No you don't. If you have

int x;

and you want to place a value into that location, you simply write
"x = value;". There is no need whatsoever to take the address of
x. Same thing.

char *p;

p = somepointer;

One of us is missing the point(er). :)

Given an array..

char arr[] = "Hello World";

...we all know that expressing arr 'decays' to a pointer to the first
element, the 'H'. Knowing this we can do..

char *ptr = arr;

... and now we can express arr[6] or ptr[6] yielding 'W' and nobody
knows the difference.

Paraphrasing the OP, we have two given definitions..

char *apc1[] = {"a", "ab", 0};
char *apc2[] = {"A", "AB", 0};

Both of these define an array [3] of pointers to char. Expressing
the array yields a pointer to its first element, a pointer to char. So..

char **papc = apc1;

...will allow apc1 and papc to behave identically in array notation.
The expression (apc1[1] == papc[1]) is true. Depending on (cond) to
choose papc..

char **papc;
papc = (cond) ? apc1 : apc2;

...is the way it's done.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top