Non-constant initializers

Discussion in 'C Programming' started by Fred the Freshwater Catfish, May 12, 2011.

  1. Hey guys,

    I've been writing some code that I would prefer to be maximally
    portable. As I have mostly used Linux, gcc is pretty much the only C
    compiler I've ever used under UN*X. I'd like to use non-constant
    initializers for some global variables. I'm pretty sure I can get it
    to work the way I want under gcc, but what of other compilers? The
    gcc documentation in info format says that ISO C99 allows this, and so
    I expect some compilers built in the 90's will support the feature,
    but to what extent is this true?

    What I mean to learn is the general prevalence of this C feature. If
    there's no support for certain well-known platforms (maybe SunOS or
    OSF/1, whatever) I may consider a different solution to the original
    problem, but I'd like to know what I'm getting in to before I start
    trying to read the docs for every bloody C compiler that ever hit the
    'net in the last twenty years.

    Thanks if you can shed any light on this subject.



    Fred the Freshwater Catfish
     
    Fred the Freshwater Catfish, May 12, 2011
    #1
    1. Advertisements

  2. Fred the Freshwater Catfish

    Ian Collins Guest

    How do you derive the initialiser values?
     
    Ian Collins, May 13, 2011
    #2
    1. Advertisements

  3. Fred the Freshwater Catfish

    Shao Miller Guest

    Could you please share an example of what kind of non-constant you'd be
    inclined to initialize a static-duration, file-scoped object with? Are
    you talking about using a function's return value? Are you talking
    about using the address of something whose address you don't know at
    some point in time?
     
    Shao Miller, May 13, 2011
    #3
  4. It should end up being a function call most of the time.



    Fred the Freshwater Catfish
     
    Fred the Freshwater Catfish, May 13, 2011
    #4
  5. Fred the Freshwater Catfish

    Ian Collins Guest

    Then you either want C++, or a singleton fiddle as posted else-thread.
     
    Ian Collins, May 13, 2011
    #5
  6. Fred the Freshwater Catfish

    Uncle Steve Guest

    Essentially, I'm looking to seed a few critical global variables with
    run-time computed values. Obviously, this will be the product of a
    function call. I would like to declare:

    int foops[] = howmuchfoo(void);

    and have everything work as I expect. Pie in the sky for non-recent
    UN*Xes?



    Regards,

    Uncle Steve
     
    Uncle Steve, May 13, 2011
    #6
  7. Hey, is that how you ancients did things in the 80's era? I hope
    there's a better way.



    Fred the Freshwater Catfish
     
    Fred the Freshwater Catfish, May 13, 2011
    #7
  8. Sorry, I'm not using C++.



    Fred the Freshwater Catfish
     
    Fred the Freshwater Catfish, May 13, 2011
    #8
  9. Fred the Freshwater Catfish

    Ian Collins Guest

    But you require a C++ feature...

    You could compile all but main() as C and compile the source file
    containing main() and your initialisers as C++.
     
    Ian Collins, May 13, 2011
    #9
  10. Or, rather than using a non-constant initializer, you can call a routine
    from main() that initialize the objects.
     
    Keith Thompson, May 13, 2011
    #10
  11. Fred the Freshwater Catfish

    Shao Miller Guest

    Are you the same person as "Fred the Freshwater Catfish"? Or are you
    another person who also wishes to accomplish this type of thing?
    Some more questions:

    - When do you wish this initialization to occur? Prior to main()?

    - Could you employ and enjoy an init() function which would initialize
    these objects, then make that the first call inside main()?

    - In your code example, is howmuchfoo() supposed to be returning an
    array of 'int' or a single 'int'?

    - Is your request a matter of being able to read, in your code, what
    will be computed for an object in the immediate vicinity of the object,
    rather than in another place (such as an init() function)?

    - Would you be willing to use macros to accomplish this?
     
    Shao Miller, May 13, 2011
    #11
  12. Fred the Freshwater Catfish

    Joe Pfeiffer Guest

    Where does the documentation say this is allowed by C99? The C99
    standard says

    All the expressions in an initializer for an object that has static
    storage duration shall be constant expressions or string literals.

    (Section 6.7.8 paragraph 4)
     
    Joe Pfeiffer, May 13, 2011
    #12
  13. Fred the Freshwater Catfish

    Seebs Guest

    IMHO, incoherent. When, EXACTLY, do you want "howmuchfoo()" to run?
    Do you anticipate that main() will have been called yet? Do you expect
    the C library to be available?

    The reason the singleton hack exists is that what you want here is something
    that's only meaningfully specified in C++.

    -s
     
    Seebs, May 13, 2011
    #13
  14. I think this is the relevant section of the gcc document:

    6.23 Non-Constant Initializers
    ==============================

    As in standard C++ and ISO C99, the elements of an aggregate
    initializer for an automatic variable are not required to
    be constant expressions in GNU C. Here is an example of an
    initializer with run-time varying elements:

    foo (float f, float g)
    {
    float beat_freqs[2] = { f-g, f+g };
    /* ... */
    }

    C90 requires constant expression for all initializers. C99 permits
    non-constant expressions, but only for automatic variables.
     
    Keith Thompson, May 13, 2011
    #14
  15. Fred the Freshwater Catfish

    Joe Pfeiffer Guest

    The OP said he wanted non-constant initializers for global variables,
    not for automatic variables.
     
    Joe Pfeiffer, May 13, 2011
    #15
  16. Fred the Freshwater Catfish

    Seebs Guest

    (Followups to comp.lang.c only, this has nothing to do with comp.arch.)

    Yes. But the question was where in the gcc docs there was anything about
    C99 allowing non-constant initializers. The answer is, there. Only, as
    you note, it doesn't say it about globals.

    -s
     
    Seebs, May 13, 2011
    #16
  17. Fred the Freshwater Catfish

    Joe Pfeiffer Guest

    As the guy who asked the question ("where in the GCC docs?"), I did
    indeed mean non-constant initializers for globals when I said "this".
    To restore the relevant context you deleted:
     
    Joe Pfeiffer, May 13, 2011
    #17
  18. Fred the Freshwater Catfish

    Seebs Guest

    Yeah. I think that the rationale of the response was roughly:
    * Obviously, it doesn't
    * But there is a section of the docs which refers to C99 and
    to non-constant initializers
    * Presenting that could explain where the confusion came from
    that led someone to think that gcc's docs said that C99
    allowed this

    -s
     
    Seebs, May 13, 2011
    #18
  19. I figured out my problem. First, the docs:

    File: gcc-4.5.info, Node: Initializers, Next: Compound Literals, Prev:
    Pointer Arith, Up: C Extensions

    6.23 Non-Constant Initializers
    ==============================

    As in standard C++ and ISO C99, the elements of an aggregate
    initializer for an automatic variable are not required to be constant
    expressions in GNU C. Here is an example of an initializer with
    run-time varying elements:

    foo (float f, float g)
    {
    float beat_freqs[2] = { f-g, f+g };
    /* ... */
    }



    1 #include <stdio.h>
    2 #include <fcntl.h>
    3 #include <stdlib.h>

    5 int * initialize(void)
    6 {
    7 int *p;
    8 int fd;
    9
    10 fd = open("/dev/urandom", O_RDONLY);
    11 if(-1 == fd) {
    12 perror("open()");
    13 exit(1);
    14 }
    15
    16 read(fd, p, sizeof(int *));
    17
    18 return(p);
    19 }
    20
    21 main(int argc, char ** argv)
    22 {
    23 int * glob = initialize();
    24
    25 fprintf(stdout, "glob = %d\n", glob);
    26
    27 exit(0);
    28 }

    So I thought I could move the "glob = initialize()" call out of main()
    and have a convenient way to set up global variables. This is the
    problem of designing vaporware when there are a lot of details to
    manage. I'll just have to arrange to load/save my globals with a
    little bit more work. Anyhow, my initial question was related to
    efforts to avoid using compilerisms which might lead to portability
    issues. As my project approaches alpha-release material, I'm trying
    to plan ahead enough to avoid massive rewrites in stuff that could
    limit portability.

    Sorry for my misinterpretation of gcc capabilities.



    Fred the Freshwater Catfish
     
    Fred the Freshwater Catfish, May 14, 2011
    #19
  20. I guess, but then my code would be tainted by C++. I'd rather avoid
    requiring C++ in the build toolchain to compile the software.


    Fred the Freshwater Catfish
     
    Fred the Freshwater Catfish, May 14, 2011
    #20
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.