[Bug c/89667] initializers for character string arrays (char *[]) appear to reside in protected storage

2019-03-16 Thread rick at regreer dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89667

--- Comment #5 from Rick Greer  ---
OK, now I get it.  The array of pointers is, indeed, static but the compiler is
trying to allocate the data that those pointers reference on the stack!  I was
confused by the fact that C++ lets me do this:

   void foo () { static char *bar[] = { (const char []){"xxx"} };

whereas C does not (of course, C++ allows stuff like:

switch (x) { case "abc"[0]: ... }

as well).  C++ is assuming that 'const' implies static, which isn't necessarily
the case.  While the simplest way to implement 'const' data is to stick it at
the end of the protected code space, you could also have a function prologue
that allocates automatic 'const' data on an appropriate page boundary,
initializes it as indicated, and then asks the operating system to dink with
the page tables to make the data read-only.  Not the most efficient
implementation, perhaps, but pedantically more correct than what C++ actually
does!

What I was (unknowingly) looking for was a way of explicitly specifying a
literal's storage class.  Something like:

 (static char []) {"foo"}

which is, of course, syntactically bogus.

Thanks again for the enlightenment, sensei.

[Bug c/89667] initializers for character string arrays (char *[]) appear to reside in protected storage

2019-03-15 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89667

--- Comment #4 from joseph at codesourcery dot com  ---
On Fri, 15 Mar 2019, rick at regreer dot net wrote:

> But can you explain why:
> 
>  static char *foo[] = { (char []){"this compiles ..."} };
> 
>  void but() { static char *bar[] = { (char []){"this doesn't!"} }; }
> 
> I.e, why is the (char []) a non-constant element when it appears in a
> function?

A compound literal outside a function is an object with static storage 
duration, so has a constant address.

A compound literal inside a function is an object with automatic storage 
duration, so has an address (on the stack) only determined on entry to the 
function, so cannot be used in a static initializer.

[Bug c/89667] initializers for character string arrays (char *[]) appear to reside in protected storage

2019-03-15 Thread rick at regreer dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89667

--- Comment #3 from Rick Greer  ---
Thanks guys, the compound literal works for me.

But can you explain why:

 static char *foo[] = { (char []){"this compiles ..."} };

 void but() { static char *bar[] = { (char []){"this doesn't!"} }; }

I.e, why is the (char []) a non-constant element when it appears in a
function?

[Bug c/89667] initializers for character string arrays (char *[]) appear to reside in protected storage

2019-03-13 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89667

--- Comment #2 from joseph at codesourcery dot com  ---
Or if for some reason you need an array of pointers to writable strings, 
you can use e.g. (char []) { "foo" }, a compound literal, as the 
initializer for such a pointer, instead of a simple string constant.

[Bug c/89667] initializers for character string arrays (char *[]) appear to reside in protected storage

2019-03-11 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89667

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 CC||jakub at gcc dot gnu.org
 Resolution|--- |INVALID

--- Comment #1 from Jakub Jelinek  ---
That is not a bug, that is how C works.  You'd need gcc older than 4.0 and use
-fwritable-strings option if you'd need it to work.  Or just use the named char
array variables initialized with string literals which is the portable way of
making strings writable.