Re: __initdata and string tables, usage consensus?

Rafael Reilova (rreilova@ececs.uc.edu)
Tue, 14 Jul 1998 15:40:55 -0400 (EDT)


Hi Jamie,

On Tue, 14 Jul 1998, Jamie Lokier wrote:

> I wrote:
> > I've just tried this __initstr macro, it works on strings inside
> > functions, but you can't use it to initialise static or global tables of
> > strings :-( Might give someone some ideas though.

Very nice, but only works when using egcs, not with gcc 2.7.2. I get:

test_initstr.c:11: section attribute cannot be specified for local variables

As long as gcc 2.7.2 is the prefered compiler for the kernel, we'll have
to name the strings outside the function if we want to use __attribute__
on them. Which very ugly for things like format strings (i.e. "%d.%d
stepping"). So I guess those will stay in ro.data for some time.

> To be more specific, you can't my __initstr to initialise tables like
> this. The compiler complains that the initialisers aren't constant. If
> you use the C++ compiler {:-)} this is allowed, but it's worse as you
> get two copies of each string in the output, one __initdata and one not.
> (Using EGCS 1.0.2).
>
> static const char * my_table [] =
> { __initstr ("First"), __initstr ("Second") };
>
> But you can always initialise string tables like this:
>
> static const char my_table [][7] __initdata =
> { "First", "Second" };
>
> The latter generally wastes space, but being __initdata it is only
> temporarily wasted. I'd say it's ok for small tables but not large ones.
> You have to be careful with the string length ([7]), as you don't get an
> error or a warning if this is large enough to hold the longest string
> without the trailing zero. If it matters.

Yes, be *very* careful. Still, I decided to use this method (2d array)
for my tables since they are small. In such cases, remember that the
pointers themselves (if using a ragged array), take up four bytes each. So
the wastage might be mitigated by the savings on the pointers.

> Constructs like this that aren't static/global initialisers work fine
> with __initstr:
>
> const char * breakage =
> broken ? __initstr ("totally broken") : __initstr ("working great");
>
> printk (__initstr ("Your %s is %s."), device, breakage);

Looks very neat!, but only works with egcs :-(

I assume this probably works with gcc 2.8 too. Maybe by 2.3, gcc 2.8.x
(where x > 1) might have gained the confidence of kernel hackers?
Experimental compilers are no-no for production kernels though.

Cheers,

Rafael

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html