#defining an array within another in C language

Discussion in 'C Programming' started by prix prad, Mar 8, 2008.

  1. prix prad

    prix prad Guest

    Hi All,
    I am trying to create two arrays at compile time using the
    #define statement.
    I am getting a compilation errors due to this;
    ***************************************************************************************************
    debug_flag_size.c: In function `main':
    debug_flag_size.c:32: error: syntax error before ';' token
    debug_flag_size.c:33: error: syntax error before '}' token
    debug_flag_size.c: At top level:
    debug_flag_size.c:44: error: syntax error before string constant
    debug_flag_size.c:44: error: conflicting types for 'printf'
    debug_flag_size.c:44: note: a parameter list with an ellipsis can't
    match an empty parameter name list declaration
    debug_flag_size.c:44: error: conflicting types for 'printf'
    debug_flag_size.c:44: note: a parameter list with an ellipsis can't
    match an empty parameter name list declaration
    debug_flag_size.c:44: warning: data definition has no type or storage
    class
    ***************************************************************************************************

    How can I do the defining of this such arrays. I don't know how many
    ELEM types are there.

    The code is :
    ****************************************************************************************************
    typedef struct new_type_ new_type;

    struct new_type_ {
    int var;
    const num_array arr[0];
    };

    #define START 0xABCDEF12;

    #define MIDDLE(arr) const new_type M ## arr = {\
    START,\
    MIDDLE_OLD(arr)\
    };

    #define MIDDLE_OLD(arr) num_array arr[] = {
    #define ELEM(a,b,c) {a, b, c},
    #define ELEM_END {-1,-1,-1}};

    main() {
    MIDDLE(abc)
    ELEM(2,3,5)
    ELEM(8,9,15)
    ELEM(15,30,50)
    ELEM(10,11,12)
    ELEM_END
    printf("\n Hi");

    return 1;
    }
    *******************************************************************************************************
    prix prad, Mar 8, 2008
    #1
    1. Advertising

  2. prix prad

    Michael Mair Guest

    prix prad wrote:
    > Hi All,
    > I am trying to create two arrays at compile time using the
    > #define statement.


    I am seeing only one, that may be part of the problem.

    > I am getting a compilation errors due to this;
    > ***************************************************************************************************
    > debug_flag_size.c: In function `main':
    > debug_flag_size.c:32: error: syntax error before ';' token
    > debug_flag_size.c:33: error: syntax error before '}' token
    > debug_flag_size.c: At top level:
    > debug_flag_size.c:44: error: syntax error before string constant
    > debug_flag_size.c:44: error: conflicting types for 'printf'
    > debug_flag_size.c:44: note: a parameter list with an ellipsis can't
    > match an empty parameter name list declaration
    > debug_flag_size.c:44: error: conflicting types for 'printf'
    > debug_flag_size.c:44: note: a parameter list with an ellipsis can't
    > match an empty parameter name list declaration
    > debug_flag_size.c:44: warning: data definition has no type or storage
    > class
    > ***************************************************************************************************
    >
    > How can I do the defining of this such arrays. I don't know how many
    > ELEM types are there.


    You mean, you do not know the number of elements of the array.


    >
    > The code is :
    > ****************************************************************************************************
    > typedef struct new_type_ new_type;
    >
    > struct new_type_ {
    > int var;
    > const num_array arr[0];


    num_array? I'll assume
    typedef int num_array[3];

    > };


    Note that this is not standard C; you may want to look either at
    C99 flexible array members or the plain old "struct hack".

    >
    > #define START 0xABCDEF12;


    Note that ";" seldom is a good idea at the end of a macro --
    you change a couple of things and everything will break.

    >
    > #define MIDDLE(arr) const new_type M ## arr = {\
    > START,\


    And here it breaks.

    > MIDDLE_OLD(arr)\
    > };


    And here is another semicolon that will break things
    if MIDDLE is abused (im)properly.

    >
    > #define MIDDLE_OLD(arr) num_array arr[] = {


    Think about how this expands -- this would never compile
    when written out but inside macros it should work?

    > #define ELEM(a,b,c) {a, b, c},


    For "," similar things apply; if you use the above in
    the wrong context, you may end up with a , operator, or
    something separating a list of init values from another
    declared variable or ...

    > #define ELEM_END {-1,-1,-1}};


    How is this supposed to work?
    Note that it is potentially wasteful to have this large
    "terminating array".

    >
    > main() {
    > MIDDLE(abc)
    > ELEM(2,3,5)
    > ELEM(8,9,15)
    > ELEM(15,30,50)
    > ELEM(10,11,12)
    > ELEM_END
    > printf("\n Hi");
    >
    > return 1;


    I suggest
    #include <stdio.h>
    #include <stdlib.h>
    at the beginning of the "file" and
    return EXIT_FAILURE;
    here.
    Note that not outputting a '\n' as last character may lead
    to your not seeing any output at all.
    > }
    > *******************************************************************************************************


    What you want to have is a struct type containing an array that
    is exactly as large as needed.
    That is not possible in C.
    What you can have is
    struct myArrStruct {
    int var;
    size_t arrSize;
    const num_array *arr;
    };

    num_array myArray[] = {
    ELEM(1,2,3),
    ELEM(4,5,6),
    ELEM(7,8,9)
    };
    struct myArrStruct myStruct = { ID, ARR_DESC(myArray)};

    where
    #define ARR_DESC(A) ((sizeof (A))/(sizeof (A[0]))), A
    #define ELEM(a, b, c) {(a), (b), (c)}

    If you really do not want to type "," in your init lists,
    then I'd suggest
    #define START_ELEM(a, b, c) {(a), (b), (c)}
    #define ELEM(a, b, c) , {(a), (b), (c)}
    rather than using an END_ELEM. It often is easier to keep
    track of the first element.
    num_array myArray[] = {
    START_ELEM()
    ELEM()
    ELEM()
    };

    The above approach has the advantage that you also can
    allocate storage dynamically and assign it to the arr member.

    If you really, really want to hide the num_Array, you can
    try to get creative.
    The opposite way, doing everything explicitly, usually is
    an even better idea.

    Here is the complete programme; I did not check it thoroughly.

    #include <stdio.h>
    #include <stdlib.h>

    typedef int num_array[3];
    struct myArrStruct {
    int var;
    size_t arrSize;
    num_array *arr;
    };

    #define ARR_DESC(A) ((sizeof (A))/(sizeof (A[0]))), A
    #define START_ELEM(a, b, c) {(a), (b), (c)}
    #define ELEM(a, b, c) , {(a), (b), (c)}

    #define ID 0xABCDEF12

    int main (void) {
    num_array myArray[] = {
    START_ELEM(1, 2, 3)
    ELEM(4, 5, 6)
    ELEM(7, 8, 9)
    };
    struct myArrStruct myStruct = { ID, ARR_DESC(myArray)};

    puts("\n Hi");

    return EXIT_FAILURE;
    }


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Mar 8, 2008
    #2
    1. Advertising

  3. prix prad

    prix prad Guest

    On Mar 8, 12:10 am, Michael Mair <> wrote:
    > prix prad wrote:
    > > Hi All,
    > >          I am trying to create two arrays at compile time using the
    > > #define statement.

    >
    > I am seeing only one, that may be part of the problem.
    >
    >
    >
    >
    >
    > > I am getting a  compilation errors due to this;
    > > ***************************************************************************­************************
    > > debug_flag_size.c: In function `main':
    > > debug_flag_size.c:32: error: syntax error before ';' token
    > > debug_flag_size.c:33: error: syntax error before '}' token
    > > debug_flag_size.c: At top level:
    > > debug_flag_size.c:44: error: syntax error before string constant
    > > debug_flag_size.c:44: error: conflicting types for 'printf'
    > > debug_flag_size.c:44: note: a parameter list with an ellipsis can't
    > > match an empty parameter name list declaration
    > > debug_flag_size.c:44: error: conflicting types for 'printf'
    > > debug_flag_size.c:44: note: a parameter list with an ellipsis can't
    > > match an empty parameter name list declaration
    > > debug_flag_size.c:44: warning: data definition has no type or storage
    > > class
    > > ***************************************************************************­************************

    >
    > > How can I do the defining of this such arrays. I don't know how many
    > > ELEM types are there.

    >
    > You mean, you do not know the number of elements of the array.
    >
    >
    >
    > > The code is :
    > > ***************************************************************************­*************************
    > > typedef struct new_type_ new_type;

    >
    > > struct new_type_ {
    > >     int var;
    > >     const num_array arr[0];

    >
    > num_array? I'll assume
    >   typedef int num_array[3];
    >
    > > };

    >
    > Note that this is not standard C; you may want to look either at
    > C99 flexible array members or the plain old "struct hack".
    >
    >
    >
    > > #define START 0xABCDEF12;

    >
    > Note that ";" seldom is a good idea at the end of a macro --
    > you change a couple of things and everything will break.
    >
    >
    >
    > > #define MIDDLE(arr) const new_type M ## arr = {\
    > > START,\

    >
    > And here it breaks.
    >
    > > MIDDLE_OLD(arr)\
    > > };

    >
    > And here is another semicolon that will break things
    > if MIDDLE is abused (im)properly.
    >
    >
    >
    > > #define MIDDLE_OLD(arr)   num_array arr[] = {

    >
    > Think about how this expands -- this would never compile
    > when written out but inside macros it should work?
    >
    > > #define ELEM(a,b,c) {a, b, c},

    >
    > For "," similar things apply; if you use the above in
    > the wrong context, you may end up with a , operator, or
    > something separating a list of init values from another
    > declared variable or ...
    >
    > > #define ELEM_END {-1,-1,-1}};

    >
    > How is this supposed to work?
    > Note that it is potentially wasteful to have this large
    > "terminating array".
    >
    >
    >
    > > main() {
    > >     MIDDLE(abc)
    > >     ELEM(2,3,5)
    > >     ELEM(8,9,15)
    > >     ELEM(15,30,50)
    > >     ELEM(10,11,12)
    > >     ELEM_END
    > >     printf("\n Hi");

    >
    > >     return 1;

    >
    > I suggest
    >   #include <stdio.h>
    >   #include <stdlib.h>
    > at the beginning of the "file" and
    >   return EXIT_FAILURE;
    > here.
    > Note that not outputting a '\n' as last character may lead
    > to your not seeing any output at all.
    >
    > > }
    > > ***************************************************************************­****************************

    >
    > What you want to have is a struct type containing an array that
    > is exactly as large as needed.
    > That is not possible in C.
    > What you can have is
    >   struct myArrStruct {
    >     int             var;
    >     size_t          arrSize;
    >     const num_array *arr;
    >   };
    >
    >   num_array myArray[] = {
    >     ELEM(1,2,3),
    >     ELEM(4,5,6),
    >     ELEM(7,8,9)
    >   };
    >   struct myArrStruct myStruct = { ID, ARR_DESC(myArray)};
    >
    > where
    >   #define ARR_DESC(A)   ((sizeof (A))/(sizeof (A[0]))), A
    >   #define ELEM(a, b, c) {(a), (b), (c)}
    >
    > If you really do not want to type "," in your init lists,
    > then I'd suggest
    >   #define START_ELEM(a, b, c) {(a), (b), (c)}
    >   #define ELEM(a, b, c)       , {(a), (b), (c)}
    > rather than using an END_ELEM. It often is easier to keep
    > track of the first element.
    >   num_array myArray[] = {
    >     START_ELEM()
    >     ELEM()
    >     ELEM()
    >   };
    >
    > The above approach has the advantage that you also can
    > allocate storage dynamically and assign it to the arr member.
    >
    > If you really, really want to hide the num_Array, you can
    > try to get creative.
    > The opposite way, doing everything explicitly, usually is
    > an even better idea.
    >
    > Here is the complete programme; I did not check it thoroughly.
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef int num_array[3];
    > struct myArrStruct {
    >    int             var;
    >    size_t          arrSize;
    >    num_array *arr;
    >
    > };
    >
    > #define ARR_DESC(A) ((sizeof (A))/(sizeof (A[0]))), A
    > #define START_ELEM(a, b, c) {(a), (b), (c)}
    > #define ELEM(a, b, c)       , {(a), (b), (c)}
    >
    > #define ID 0xABCDEF12
    >
    > int main (void) {
    >    num_array myArray[] = {
    >     START_ELEM(1, 2, 3)
    >     ELEM(4, 5, 6)
    >     ELEM(7, 8, 9)
    >    };
    >    struct myArrStruct myStruct = { ID, ARR_DESC(myArray)};
    >
    >    puts("\n Hi");
    >
    >    return EXIT_FAILURE;
    >
    > }
    >
    > Cheers
    >   Michael
    > --
    > E-Mail: Mine is an   /at/ gmx /dot/ de   address.- Hide quoted text -
    >
    > - Show quoted text -


    Hi All,
    First of all, thanks Michael for the reply. I shouldn't
    have ended the
    #define START 0xABCDEF12 with a semicolon. Removing that fixed one
    error though I am hitting others.
    Let me be more specific here about what I am trying to
    achieve. The above program posted here is a demo one; the actual
    specifics are a little different. I am working with a few things here
    that cannot be changed.
    The structure of each ELEM is of the form

    **************************************************************************************
    typedef struct num_array_ num_array;

    struct num_array_{
    boolean *var;
    char *txt;
    int num;
    }
    **************************************************************************************
    in a header file say foo.h. This is a structure in the pre-existing
    code. Using this structure we construct an array like :

    *************************************************************************************
    #define ARRAY(array_name) const num_array = {
    #define MEMBER(variable, enum, text) {&variable, text},
    #define ARRAY_END { (boolean *)NULL, (char *) NULL } };
    *************************************************************************************

    Now many .c files include foo.h and define something like this for
    file1.c:
    *************************************************************************************
    ARRAY(file1_array)
    MEMBER(file1_var1, ENUM_1, "FILE 1's first variable")
    MEMBER(file1_var2, ENUM_2, "FILE 1's second variable")
    .
    .
    .
    MEMBER(file1_varN, ENUM_N, "FILE 1's Nth variable")
    ARRAY_END
    *************************************************************************************

    A file can have any number of members; hence I said that 'I don't know
    the number of elements of the array'

    Now I want to do add a START and an END delimiter for each array
    defined in this way.

    I can do:
    *********************************************************************************************
    #define START_DELIMITER 0xABCDEF12
    #define END_DELIMITER 0xFEDCBA21

    #define ARRAY(array_name) const num_array[] = {\
    {(boolean *)START_DELIMITER,
    (char *) START_DELIMITER}
    #define MEMBER(variable, enum, text) ,{&variable, text}
    #define ARRAY_END ,{(boolean *)NULL, (char *)
    NULL }\
    ,{(boolean *)END_DELIMITER,
    (char *) END_DELIMITER};
    *********************************************************************************************

    After 'bounding' each array in this way; when the program gets
    executed I can use these 2 delimiters to locate 'each' of such arrays
    so that I can do processing on them.

    However I am unable to add the START_DELIMITER as the .c files do
    something like this:
    Say for file1.c

    ******************************************************************************************
    for(int i=0; file1_array.var; i++)
    {
    *(file1_array.var) = TRUE;
    }

    ******************************************************************************************

    Adding the START_DELIMITER would push the other members down by 1
    row and
    dereferencing the var member of the file1_array[0] would crah the
    program since we are trying to do *(0xABCDEF12).

    The simple approach would have been that the .c files now change
    their code to start processing from the first element of the
    array......say
    *************************************************************************************
    for(int i=1; file1_array.var; i++)
    {
    *(file1_array.var) = TRUE;
    }
    *************************************************************************************

    This will certainly solve the problem; however that code needs to be
    unchanged.



    However just inserting the END_DELIMITER is not enough as I don't know
    how many members each array has unless I do some processing in the
    header file itself (don't want to do that)

    So my intention is to 'wrap' the original array with the
    START_DELIMITER and the END_DELIMITER or just the START_DELIMITER
    (since I can embed the END_DELIMITER as shown above).

    Hence how could one do that?

    I was trying to do:

    #define START { (boolean *)START_DELIMITER, (char *)START_DELIMITER}

    typedef new_type_ new_type;
    struct new_type_ {
    num_array start;
    num_array data[]; /* The flexible array member */
    }

    However using the flexible array member gives the error:
    'non-static initialization of a flexible array member'

    Hence used :
    struct new_type_ {
    num_array start;
    num_array data[0];
    }



    #define ARRAY(array_name) const new_type NEW ## array_name = {
    START
    #define ARRAY_INTERNAL(array_name) const num_array array_name[] = {
    #define MEMBER(variable, enum, text) ,{&variable, text}
    #define ARRAY_END ,{(boolean *)NULL, (char *)
    NULL }\
    ,{(boolean *)END_DELIMITER,
    (char *) END_DELIMITER};
    };

    so that when the .c code calls say the ARRAY(file1_array) I have the
    START_DELIMITER prepended
    to the array whose 'var' members will be dereferenced by that .c file.
    This is the
    original array array_name[]. array_name[] and START will provide me
    with the wrapper
    NEW_array_name which is transparent to the .c files including foo.h

    However #defining original array inside the wrapper struct does not
    seem to work as the above expansion is of the form........say file1.c
    having 2 members:
    ******************************************************************************************
    NEW_file1_array = {
    { (boolean *)START_DELIMITER, (char *)START_DELIMITER}
    const num_array array_name[] = {
    ,{&file1_var1, "FILE1's variable 1"}
    ,{&file1_var2, "FILE1's variable 2"}
    ,{(boolean *)NULL, (char *) NULL }\
    ,{(boolean *)END_DELIMITER, (char *) END_DELIMITER};
    };

    while what I wanted was:
    NEW_file1_array = {
    { (boolean *)START_DELIMITER, (char *)START_DELIMITER}
    ,{&file1_var1, "FILE1's variable 1"}
    ,{&file1_var2, "FILE1's variable 2"}
    ,{(boolean *)NULL, (char *) NULL }\
    ,{(boolean *)END_DELIMITER, (char *) END_DELIMITER}};

    Also I suppose using a definition like :
    struct new_type_ {
    num_array start;
    num_array *data;
    }

    would not help as then the ARRAY_INTERNAL would need to be defined
    like:
    #define ARRAY_INTERNAL(array_name) const num_array *array_name = {

    and this would again be incompatible with what the .c files expect as
    they operate on an array; also above expansion issues remain.


    Can anyone suggest be what I am missing here or maybe suggest a
    completely different solution to tackle such that the solution is
    implementable in the header file itself and is transparent to the .c
    files?

    Thanks,
    prix
    prix prad, Mar 8, 2008
    #3
  4. On Sat, 8 Mar 2008 02:42:31 -0800 (PST), prix prad <>
    wrote:

    snip ~200 lines of "old code" Please trim your posts when replying.

    >Hi All,
    > First of all, thanks Michael for the reply. I shouldn't
    >have ended the
    >#define START 0xABCDEF12 with a semicolon. Removing that fixed one
    >error though I am hitting others.
    > Let me be more specific here about what I am trying to
    >achieve. The above program posted here is a demo one; the actual
    >specifics are a little different. I am working with a few things here
    >that cannot be changed.
    > The structure of each ELEM is of the form
    >
    >**************************************************************************************
    >typedef struct num_array_ num_array;
    >
    >struct num_array_{
    > boolean *var;
    > char *txt;
    > int num;
    >}
    >**************************************************************************************
    >in a header file say foo.h. This is a structure in the pre-existing
    >code. Using this structure we construct an array like :
    >
    >*************************************************************************************
    >#define ARRAY(array_name) const num_array = {


    The first problem seems to be that the parameter of the macro is not
    used in its expansion. This macro will expand into a syntax error
    since num_array is a type. I think you meant
    #define ARRAY(array_name) const num_array array_name[] = {

    Hence the oft repeated advice to cut and paste your code and not
    retype it.

    >#define MEMBER(variable, enum, text) {&variable, text},


    And again the enum parameter does not appear in the expansion.

    >#define ARRAY_END { (boolean *)NULL, (char *) NULL } };


    With the exception of non-prototyped function arguments, there is
    probably never a need to cast NULL and certainly not in the
    initialization list of an array.

    >*************************************************************************************
    >
    >Now many .c files include foo.h and define something like this for
    >file1.c:
    >*************************************************************************************
    >ARRAY(file1_array)
    >MEMBER(file1_var1, ENUM_1, "FILE 1's first variable")
    >MEMBER(file1_var2, ENUM_2, "FILE 1's second variable")
    >.
    >.
    >.
    >MEMBER(file1_varN, ENUM_N, "FILE 1's Nth variable")
    >ARRAY_END


    So this expands to
    const num_array = {
    {&file1_var1, "FILE 1's first variable"},
    {&file1_var2, "FILE 1's second variable"},
    {&file1_varN, "FILE 1's Nth variable"},
    { (boolean *)NULL, (char *) NULL } };

    Note the missing name of the array and the missing brackets in line 1.

    Note also that member num of each struct element will be set to zero
    (because it is not explicitly initialized while the rest of the
    aggregate is). Since the array is const you cannot change it in
    subsequent code.

    >*************************************************************************************
    >
    >A file can have any number of members; hence I said that 'I don't know
    >the number of elements of the array'
    >
    >Now I want to do add a START and an END delimiter for each array
    >defined in this way.
    >
    >I can do:
    >*********************************************************************************************
    >#define START_DELIMITER 0xABCDEF12
    >#define END_DELIMITER 0xFEDCBA21
    >
    >#define ARRAY(array_name) const num_array[] = {\
    > {(boolean *)START_DELIMITER,
    >(char *) START_DELIMITER}


    You fixed the missing brackets but not the missing array name.

    Though not guaranteed by the standard, on most machines a char* can
    accept any converted integer value within your program's address
    space. Are you sure the two values #define-d above do? If not, some
    systems will terminate your program at this point (merely calculating
    a bad address is sufficient to signal a fatal error).

    You have not shown us the declaration of boolean on your system. If
    it is not char, it may have some alignment requirements. Do the two
    addresses #define-d above meet those requirements. If not, then
    attempting to convert an improperly aligned address to an aligned
    pointer type invokes undefined behavior (or maybe the behavior is not
    undefined until you store in the pointer object but this
    initialization does both anyway).

    >#define MEMBER(variable, enum, text) ,{&variable, text}
    >#define ARRAY_END ,{(boolean *)NULL, (char *)
    >NULL }\
    > ,{(boolean *)END_DELIMITER,
    >(char *) END_DELIMITER};
    >*********************************************************************************************
    >
    >After 'bounding' each array in this way; when the program gets
    >executed I can use these 2 delimiters to locate 'each' of such arrays
    >so that I can do processing on them.
    >
    >However I am unable to add the START_DELIMITER as the .c files do
    >something like this:
    >Say for file1.c
    >
    >******************************************************************************************
    >for(int i=0; file1_array.var; i++)


    Defining your variables inside the for statement is not legal in C89
    and I don't think it is in C99 either.

    >{
    >*(file1_array.var) = TRUE;
    >}
    >
    >******************************************************************************************
    >
    > Adding the START_DELIMITER would push the other members down by 1
    >row and
    >dereferencing the var member of the file1_array[0] would crah the
    >program since we are trying to do *(0xABCDEF12).
    >
    > The simple approach would have been that the .c files now change
    >their code to start processing from the first element of the
    >array......say
    >*************************************************************************************
    >for(int i=1; file1_array.var; i++)
    >{
    >*(file1_array.var) = TRUE;
    >}
    >*************************************************************************************
    >
    >This will certainly solve the problem; however that code needs to be
    >unchanged.


    Instead of using the arbitrary address values, you might try something
    like:

    Define two global variables (variables with file scope), one
    boolean and the second either char or char[] (depending on how the
    object pointed to is initialized).

    Delete the two _DELIMETER macros and change ARRAY to
    #define ARRAY(array_name) const num_array array_name[] =\
    { {&global_bool,&global_char}

    snip a lot more code dealing with declarations and definitions.

    At this point it dawned on me that I am re-engineering a solution with
    no concept of the real problem you are trying to solve.

    The arrays are obviously not dynamically allocated. If they are being
    used in the function they are being defined in, then the normal
    approach of
    num_elements = array / *array;
    will work. If they are being passed to your function, then you know
    the starting address and can find the last element by looking for an
    element with two NULL pointer values.

    So instead of another 400 lines of code, try describing the problem
    rather than the solution.


    Remove del for email
    Barry Schwarz, Mar 8, 2008
    #4
  5. prix prad

    prix prad Guest

    Hi Barry,
    You have a main foo.h file having the #define statements.
    Then there are many .h/.c file pairs. The .h files say file1.h
    populates the array of structs using say
    #define ARRAY(file1)
    #define MEMBER(var1,txt1,num1)
    #define MEMBER(var2,txt2,num2)
    #define ARRAY_END

    The corresponding .c file say file1.c does processing on the arrays;
    say iterating through the
    array and setting the 'var' member of each struct to TRUE.

    My problem is that I can't modify the .h/.c files. I only want to
    modify foo.h.

    Member num of each struct is set to zero and thats fine. Also there
    are no alignnment issues. I can't get the size in the foo.h file since
    I don't know how many members each array defined will have since that
    is done in fileN.h. Thus I don't know the starting address in foo.h ;
    in fact the .c files use the exact same approach - they know the
    starting address and then they continue processing until they hit an
    element with 2 NULL pointers.


    I know the END_DELIMITER since I can append it in a transparent manner
    to the array. However I need to know either the START_DELIMITER or the
    number of elements per array.

    I was thinking of doing processing in the foo.h file itself to
    calculate the number of elements by using the currently unused 'num'
    field. However doing something like

    define MEMBER(variable, enum, text) {&variable, text, i++},

    will flag an error of 'Initializer element in not constant'

    So I need to add the START_DELIMITER with it being oblivious to the
    fileN[.h/.c] such that prepending the START_DELIMITER to the original
    array in transparent the fileN[.h/.c] files.

    So now if the new array is {START_DELIMITER, original_array} with the
    START_DELIMITER being the 1st row of the new array then
    when the .c file does

    *(array_name1[0].var) = TRUE; it should not be doing

    *(0xABCDEF12) = TRUE wherein

    START_DELIMITER = {(boolean *)0xABCDEF12, (char *)0xABCDEF12,
    (ulong)0xABCDEF12 }

    So in a nutshell the problem definition is adding a START_DELIMITER(it
    can be an int or same as num_array as above) such that this change is
    oblivious to existing unchangeable
    fileN[.h/.c] code.

    Hence I was thinking of a wrapper struct which will include the
    START_DELIMITER and the original array.

    Hope this explains the problem better.

    Thanks,
    prix
    prix prad, Mar 8, 2008
    #5
  6. On Sat, 8 Mar 2008 11:13:37 -0800 (PST), prix prad <>
    wrote:

    >Hi Barry,
    > You have a main foo.h file having the #define statements.
    >Then there are many .h/.c file pairs. The .h files say file1.h
    >populates the array of structs using say
    >#define ARRAY(file1)
    >#define MEMBER(var1,txt1,num1)
    >#define MEMBER(var2,txt2,num2)
    >#define ARRAY_END


    While file1.h can have define these macros, it should not populate any
    arrays. Objects should never be defined in headers.

    >
    >The corresponding .c file say file1.c does processing on the arrays;
    >say iterating through the
    >array and setting the 'var' member of each struct to TRUE.


    Since the struct is const, you cannot set the var member. If I
    remember you sample code, you are actually setting the object the var
    member points to which is allowed.

    >
    >My problem is that I can't modify the .h/.c files. I only want to
    >modify foo.h.


    Believe it or not but even in supposedly intelligently run businesses
    it is fairly common to hear "fix the problem but don't change
    anything".

    You haven't told us why you want to modify anything. What aspect of
    the current code's performance do you think changing/adding foo.h will
    improve/correct.

    If you cannot modify either file1.h or file1.c, how or where is foo.h
    ever going to be #include-d.

    >
    >Member num of each struct is set to zero and thats fine. Also there
    >are no alignnment issues. I can't get the size in the foo.h file since
    >I don't know how many members each array defined will have since that
    >is done in fileN.h. Thus I don't know the starting address in foo.h ;


    Nothing in foo.h should have a starting address.

    >in fact the .c files use the exact same approach - they know the
    >starting address and then they continue processing until they hit an
    >element with 2 NULL pointers.
    >
    >
    >I know the END_DELIMITER since I can append it in a transparent manner
    >to the array. However I need to know either the START_DELIMITER or the
    >number of elements per array.


    You are not describing what you want to do. You are stating
    assumptions about how you may chose to do it.

    >
    >I was thinking of doing processing in the foo.h file itself to
    >calculate the number of elements by using the currently unused 'num'
    >field. However doing something like


    There should not be any executable statements in foo.h

    >
    >define MEMBER(variable, enum, text) {&variable, text, i++},
    >
    >will flag an error of 'Initializer element in not constant'


    Unless variable has static duration, &variable is not constant either
    so your compiler is treating the two expressions differently.

    >
    >So I need to add the START_DELIMITER with it being oblivious to the
    >fileN[.h/.c] such that prepending the START_DELIMITER to the original
    >array in transparent the fileN[.h/.c] files.


    This is still a supposition about the solution. You need to define
    the requirement before even considering possible solutions.

    >
    >So now if the new array is {START_DELIMITER, original_array} with the
    >START_DELIMITER being the 1st row of the new array then
    >when the .c file does
    >
    >*(array_name1[0].var) = TRUE; it should not be doing
    >
    >*(0xABCDEF12) = TRUE wherein


    I already told you how to avoid this.

    >
    >START_DELIMITER = {(boolean *)0xABCDEF12, (char *)0xABCDEF12,
    >(ulong)0xABCDEF12 }
    >
    >So in a nutshell the problem definition is adding a START_DELIMITER(it
    >can be an int or same as num_array as above) such that this change is
    >oblivious to existing unchangeable
    >fileN[.h/.c] code.
    >
    >Hence I was thinking of a wrapper struct which will include the
    >START_DELIMITER and the original array.
    >
    >Hope this explains the problem better.


    Sorry but it doesn't. We still have no idea what you want to do. All
    you have told us the problems you face trying to do a something we
    only partially understand a particular way.


    Remove del for email
    Barry Schwarz, Mar 9, 2008
    #6
  7. prix prad

    prix prad Guest

    Hi Barry,

    On Mar 8, 7:12 pm, Barry Schwarz <> wrote:
    > On Sat, 8 Mar 2008 11:13:37 -0800 (PST), prix prad <>
    > wrote:
    >
    > >Hi Barry,
    > >         You have a main foo.h file having the #define statements..
    > >Then there are many .h/.c file pairs. The .h files say file1.h
    > >populates the array of structs using say
    > >#define ARRAY(file1)
    > >#define MEMBER(var1,txt1,num1)
    > >#define MEMBER(var2,txt2,num2)
    > >#define ARRAY_END

    >
    > While file1.h can have define these macros, it should not populate any
    > arrays.  Objects should never be defined in headers.


    My mistake in saying the #defines are in file.h; they are in foo.h.
    Currently this is happenning:

    There is an existing file foo.h
    which has all the #defines of the ARRAY, MEMBER and ARRAY_END as
    below:


    #define ARRAY(array_name) const num_array array_name[] = {
    #define MEMBER(var,txt,num) {&var, txt},
    #define ARRAY_END {(boolean *)NULL, (char *)NULL} };

    num_array is

    struct num_array {
    boolean *var;
    char *txt;
    int num;
    };

    Then there are multiple .h/.c file pairs. The .h file is including the
    foo.h file and
    creates the array say file1_array of say 2 members.

    ARRAY(file1_array)
    MEMBER(file1_var1,file1_txt1,file1_num1)
    MEMBER(file1_var2,file1_txt2,file1_num2)
    ARRAY_END

    so that array gets created for file1.h


    Then in file1.c we do something like

    *(file1_array.var) = 1; for all the array members


    >
    >
    >
    > >The corresponding .c file say file1.c does processing on the arrays;
    > >say iterating through the
    > >array and setting the 'var' member of each struct to TRUE.

    >
    > Since the struct is const, you cannot set the var member.  If I
    > remember you sample code, you are actually setting the object the var
    > member points to which is allowed.
    >
    >


    Oops ...correct....I am setting the object the var member points by
    dereferencing the
    var member first
    >
    > >My problem is that I can't modify the .h/.c files. I only want to
    > >modify foo.h.

    >
    > Believe it or not but even in supposedly intelligently run businesses
    > it is fairly common to hear "fix the problem but don't change
    > anything".
    >
    > You haven't told us why you want to modify anything.  What aspect of
    > the current code's performance do you think changing/adding foo.h will
    > improve/correct.
    >
    > If you cannot modify either file1.h or file1.c, how or where is foo.h
    > ever going to be #include-d.
    >
    >

    Forgot to mention I suppose; all fileN.h files include foo.h currently
    in the above
    format where we have #define of ARRAY, MEMBER and ARRAY_DONE.

    So the issue is changing foo.h so that I know the length/number of
    elements of the array
    by adding a START_DELIMITER and END_DELIMITER. Adding these two
    delimiters will be helpful
    when I execute the program so that I can look for them in the
    executable and store the location of all the MEMBERS of all the arrays
    in a continuous location. Currently the arrays are there but in
    a non-contiguous location and I don't know how big each array is ;
    since I don't know the number of elements.


    >
    > >Member num of each struct is set to zero and thats fine. Also there
    > >are no alignnment issues. I can't get the size in the foo.h file since
    > >I don't know how many members each array defined will have since that
    > >is done in fileN.h. Thus I don't know the starting address in foo.h ;

    >
    > Nothing in foo.h should have a starting address.


    Yes true; what I was alluding to is that I don't know the starting
    address of each array in the executable since they are in non-
    contiguous locations.

    >
    > >in fact the .c files use the exact same approach - they know the
    > >starting address and then they continue processing until they hit an
    > >element with 2 NULL pointers.

    >
    > >I know the END_DELIMITER since I can append it in a transparent manner
    > >to the array. However I need to know either the START_DELIMITER or the
    > >number of elements per array.

    >
    > You are not describing what you want to do.  You are stating
    > assumptions about how you may chose to do it.
    >
    >
    >
    > >I was thinking of doing processing in the foo.h file itself to
    > >calculate the number of elements by using the currently unused 'num'
    > >field. However doing something like

    >
    > There should not be any executable statements in foo.h
    >


    Yes true, thats add to the difficulty of solving this. Hence was
    thinking about preprocessor macros to arrive to a solution.

    >
    >
    > >define MEMBER(variable, enum, text) {&variable, text, i++},

    >
    > >will flag an error of 'Initializer element in not constant'

    >
    > Unless variable has static duration, &variable is not constant either
    > so your compiler is treating the two expressions differently.
    >
    >
    >
    > >So I need to add the START_DELIMITER with it being oblivious to the
    > >fileN[.h/.c] such that prepending the START_DELIMITER to the original
    > >array in transparent the fileN[.h/.c] files.

    >
    > This is still a supposition about the solution.  You need to define
    > the requirement before even considering possible solutions.
    >
    >
    >
    > >So now if the new array is {START_DELIMITER, original_array} with the
    > >START_DELIMITER being the 1st row of the new array then
    > >when the .c file does

    >
    > >*(array_name1[0].var) = TRUE; it should not be doing

    >
    > >*(0xABCDEF12) = TRUE wherein

    >
    > I already told you how to avoid this.
    >
    >


    >
    > >START_DELIMITER = {(boolean *)0xABCDEF12, (char *)0xABCDEF12,
    > >(ulong)0xABCDEF12 }

    >
    > >So in a nutshell the problem definition is adding a START_DELIMITER(it
    > >can be an int or same as num_array as above) such that this change is
    > >oblivious to existing unchangeable
    > >fileN[.h/.c] code.

    >
    > >Hence I was thinking of a wrapper struct which will include the
    > >START_DELIMITER and the original array.

    >
    > >Hope this explains the problem better.

    >
    > Sorry but it doesn't.  We still have no idea what you want to do.  All
    > you have told us the problems you face trying to do a something we
    > only partially understand a particular way.
    >
    > Remove del for email



    I want to find out the bounds of each of the arrays in the fileN.h
    files so that I can group all the MEMBERS of all the array in one
    contiguous location instead of having them in disparate memory
    locations. I want to add any extra logic for doing this in foo.h file
    as against in the fileN[.h/.c]
    files.

    So the problem is that I don't know where these arrays are stored in
    memory during compilation, and i need to know their location at
    runtime so that I can group them together.

    Thanks,
    prix
    prix prad, Mar 9, 2008
    #7
  8. On Sun, 9 Mar 2008 01:45:51 -0800 (PST), prix prad <>
    wrote:

    >Hi Barry,


    >I want to find out the bounds of each of the arrays in the fileN.h
    >files so that I can group all the MEMBERS of all the array in one
    >contiguous location instead of having them in disparate memory
    >locations. I want to add any extra logic for doing this in foo.h file
    >as against in the fileN[.h/.c]
    >files.


    Again, you are giving us a potential solution, not a description of
    what is required.

    >
    >So the problem is that I don't know where these arrays are stored in
    >memory during compilation, and i need to know their location at
    >runtime so that I can group them together.


    You cannot move an array once it has been defined. If they are in
    different functions, they are going to stay there. Even if they are
    in the same function they need not be contiguous.

    Why do you need to know the location of any array? Do you have a new
    function which is going to do something to the values in the array
    (actually values pointed to by members of elements of the array since
    the array itself is const)? If so, how is this function being called?
    If not, how are you going to do anything with the data?


    Remove del for email
    Barry Schwarz, Mar 10, 2008
    #8
  9. prix prad

    prix prad Guest

    Hi Barry,
    On Mar 9, 5:27 pm, Barry Schwarz <> wrote:
    > On Sun, 9 Mar 2008 01:45:51 -0800 (PST), prix prad <>
    > wrote:
    >
    >
    > Again, you are giving us a potential solution, not a description of
    > what is required.  





    > You cannot move an array once it has been defined.  If they are in
    > different functions, they are going to stay there.  Even if they are
    > in the same function they need not be contiguous.


    I should have been more specific. I want to group only specific
    members of the
    array......they being the address of the 'var' member and the 'txt'
    string.
    I will create a new array of structures using these 2 members with the
    structure containing
    2 members which are the first 2 members of struct num_array. So the
    intention is to create a
    new array of structs and this array will have all the MEMBERS of all
    the ARRAYs defined
    by all the fileN.h files; but this time in a contiguous order.

    > Why do you need to know the location of any array?  Do you have a new
    > function which is going to do something to the values in the array
    > (actually values pointed to by members of elements of the array since
    > the array itself is const)?  If so, how is this function being called?
    > If not, how are you going to do anything with the data?


    Yes I intend to write a new function which will set/unset the boolean
    value. I intend to give this
    function the 'txt' string as a parameter and it will go and set the
    corresponding boolean value by looking
    up the new array that I will create using the address of var(the
    boolean) and the txt string as pairs.

    So here is the sequence of steps in short:
    (1) I compile the program with modifications such that now every
    fileN.h created array has the START and END
    DELIMITERS in addition to the existing ARRAY, 'n' number of
    MEMBERS and ARRAY_END.
    (2) Now using (1) I add functionality to create a new array of structs
    with the each structure containing the boolean address and
    the text string.
    (3) While running the program I manually enter statements to set/unset
    some of the boolean vars (0 to 1).
    Then I need to store info about which vars I have set to true and
    store the corresponding string in some file 'X'.
    (4) Then next time I run the program these vars will be set for me by
    the program by reading the 'text' strings
    from file 'X' and using the address info from the newly created
    array of structures.

    I am strongly believing now that I need to change the .h/.c files to
    make this work and changing just foo.h isn't enough.

    Regards,
    prix
    prix prad, Mar 10, 2008
    #9
  10. On Sun, 9 Mar 2008 21:27:05 -0700 (PDT), prix prad <>
    wrote:

    snip

    >Yes I intend to write a new function which will set/unset the boolean
    >value. I intend to give this


    How will this function be called if you don't change at least one of
    the .c files?

    >function the 'txt' string as a parameter and it will go and set the
    >corresponding boolean value by looking
    >up the new array that I will create using the address of var(the
    >boolean) and the txt string as pairs.


    As long as you are passing info to the function why not pass the
    address of the array also?

    >
    >So here is the sequence of steps in short:


    snip

    >I am strongly believing now that I need to change the .h/.c files to
    >make this work and changing just foo.h isn't enough.


    Good luck.


    Remove del for email
    Barry Schwarz, Mar 11, 2008
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. diffused
    Replies:
    9
    Views:
    724
    Oscar kind
    Aug 1, 2004
  2. johny smith
    Replies:
    8
    Views:
    417
    Peter Koch Larsen
    Jul 2, 2004
  3. Spiro Trikaliotis

    Array initialization when defining the array

    Spiro Trikaliotis, Jun 8, 2007, in forum: C Programming
    Replies:
    5
    Views:
    322
    Spiro Trikaliotis
    Jun 9, 2007
  4. Replies:
    28
    Views:
    1,168
  5. Glenn
    Replies:
    4
    Views:
    135
    Brian Candler
    Jan 28, 2009
Loading...

Share This Page