About a namelist...with question 
Author Message
 About a namelist...with question

Hello,

I have to modify a big program written by some smart guys, at
least they are far smarter then I am, so I'm a little bit stucked
with the following problem :

it says :" ..while such service is standard in fortran - the namelist
there is no similar facility in C. We have therefore had to roll our
own.."

typedef struct {
        char *vname;
        void *vptr;
        enum {NI, NR} vtype;
        int vlen, vstatus;

Quote:
} NameList;

#define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int));

"the way it is used  typically is"

NameList nameList[]{
        INAME(intVariable)

Quote:
}

first of all, I just don't know what is doing that #x in the #define
, I haven't found any reference to such a thing, the second is that the
compiler always says at the INAME(whatever) that NI is not declared.

can someone help me out ?

thank you,

istvan albert.



Thu, 08 Jul 1999 03:00:00 GMT  
 About a namelist...with question

Quote:

> #define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int));

> "the way it is used  typically is"

> NameList nameList[]{
>         INAME(intVariable)
> }

> first of all, I just don't know what is doing that #x in the #define

A '#x' will be converted to a string after pre-processor expansion. In
this
case, INAME(intVariable) will expand to ("intVariable", ....). This is
an
ANSI C feature and may not work with non-ansi c compilers.

--
/* Vivek Chopra */
#include <std/disclaimer.h>



Fri, 09 Jul 1999 03:00:00 GMT  
 About a namelist...with question

: it says :" ..while such service is standard in Fortran - the namelist
: there is no similar facility in C. We have therefore had to roll our
: own.."

Not sure how good my answer is going to be... I don't know what the namelist
'service' in Fortran does.

: typedef struct {
:       char *vname;
:       void *vptr;
:       enum {NI, NR} vtype;
:       int vlen, vstatus;
: } NameList;

: #define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int));

: "the way it is used  typically is"

: NameList nameList[]{
:       INAME(intVariable)
: }

: first of all, I just don't know what is doing that #x in the #define
: , I haven't found any reference to such a thing, the second is that the
: compiler always says at the INAME(whatever) that NI is not declared.

Easy one first... the compiler is right that NI is not declared. While it is
true that the variable NameList.vtype can be either NI or NR, outside this
context NI does not exist.

I'm not totally sure about this next bit. Kernighan and Ritchie cover this
(p90 in my second edition copy) and this is where my information is coming
from. As far as I can make out, the declaration:

NameList nameList[]{
        INAME(intVariable)

Quote:
}

will declare a variable _nameList_ of type _NameList_ and initialise it to
a string containing intVariable (e.g., if intVariable is 45 the #x becomes
"45"), a pointer to intVariable, either NI or NR, and an integer containing
sizeof(x)/sizeof(int). Not sure what happens to the last int (vstatus)
though.

: can someone help me out ?

Hope this is helpful.

John



Fri, 09 Jul 1999 03:00:00 GMT  
 About a namelist...with question

<snip>

Quote:
> : typedef struct {
> :  char *vname;

Because string literals must not be modified, I would declare this
`const char *' just to be safe.

Quote:
> :  void *vptr;
> :  enum {NI, NR} vtype;
> :  int vlen, vstatus;
> : } NameList;

> : #define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int));

I assume that the above line actually ends with } instead of );

By the way, even though you do not make it explicit, vstatus does get
initialized to 0.

Also, measuring in sizeof(int) is bad because sizeof(x) need not be a
multiple of sizeof(int). Just measure in terms of sizeof(char) instead
(and sizeof(char) is 1 :-).

Quote:

> : "the way it is used  typically is"

> : NameList nameList[]{
> :  INAME(intVariable)
> : }

I assume that the line should have [] = { instead of []{ and that the
whole declaration does end with a ;

Quote:

> : first of all, I just don't know what is doing that #x in the #define
> : , I haven't found any reference to such a thing, the second is that the
> : compiler always says at the INAME(whatever) that NI is not declared.

> Easy one first... the compiler is right that NI is not declared. While it is
> true that the variable NameList.vtype can be either NI or NR, outside this
> context NI does not exist.

Outside what `context'? We are talking C here, not C++. NI in this
context is very much an integral constant expression with value
0. struct does *not* introduce a new scope in C. If you are using C++,
please seek advice in comp.lang.c++.

Quote:

> I'm not totally sure about this next bit. Kernighan and Ritchie cover this
> (p90 in my second edition copy) and this is where my information is coming
> from. As far as I can make out, the declaration:

> NameList nameList[]{
>    INAME(intVariable)
> }

> will declare a variable _nameList_ of type _NameList_ and initialise it to
> a string containing intVariable (e.g., if intVariable is 45 the #x becomes

I am assuming you are saying that if IntVariable was #defined to be
45, because during preprocessing, actual vaues of variables are
immaterial. In this case, it is very bad to #define intVariable to 45,
because the macro will expand to something containing &45, which is
illegal.

Quote:
> "45"), a pointer to intVariable, either NI or NR, and an integer containing
> sizeof(x)/sizeof(int). Not sure what happens to the last int (vstatus)
> though.

No. #x expands to the string containing the replacement of x, not its
expanded value.

Quote:

> : can someone help me out ?

> Hope this is helpful.

Hmmm ...

Cheers
Tanmoy
--

Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003   voice: 1 (505) 665 4733    [ Home: 1 (505) 662 5596 ]



Mon, 12 Jul 1999 03:00:00 GMT  
 About a namelist...with question

Quote:

> Easy one first... the compiler is right that NI is not declared. While it is
> true that the variable NameList.vtype can be either NI or NR, outside this
> context NI does not exist.

  Ok.

Quote:
> I'm not totally sure about this next bit. Kernighan and Ritchie cover this
> (p90 in my second edition copy) and this is where my information is coming
> from. As far as I can make out, the declaration:

> NameList nameList[]{
>         INAME(intVariable)
> }

> will declare a variable _nameList_ of type _NameList_ and initialise it to
> a string containing intVariable (e.g., if intVariable is 45 the #x becomes
> "45"), a pointer to intVariable, either NI or NR, and an integer containing
> sizeof(x)/sizeof(int). Not sure what happens to the last int (vstatus)
> though.

This is incorrect.
#intVariable will become "intVariable" and not "45" (where 45 was the value
of intVariable. This replacement is done by the preprocessor, which has no
means of knowing the value of intVariable.

Thus INAME(intVariable) should become:
  ("intVariable", &intVariable, NI, sizeof(intVariable)/sizeof(int))

--
/* Vivek Chopra */
#include <std/disclaimer.h>



Mon, 12 Jul 1999 03:00:00 GMT  
 About a namelist...with question

Quote:

>Hello,

>I have to modify a big program written by some smart guys, at
>least they are far smarter then I am, so I'm a little bit stucked
>with the following problem :

>it says :" ..while such service is standard in Fortran - the namelist
>there is no similar facility in C. We have therefore had to roll our
>own.."

>typedef struct {
>    char *vname;
>    void *vptr;
>    enum {NI, NR} vtype;

It is not immediately clear from the standard what namespace NI and NR
are in and whether they can be used outside the struct declartion.
(I'm not saying it can't be decided by a careful reading of the
standard, just that it's not obvious.)

Quote:
>    int vlen, vstatus;
>} NameList;

This probably should be recoded

enum Vtypes {NI, NR};
typedef struct {
   char *vname;
   void *vptr;
   enum Vtypes vtype;
   int vlen, vstatus;

Quote:
} NameList;

So that it is clear to both the reader and the compiler that
the names NI and NR have namespace outside the struct.
Quote:

>#define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int));

>"the way it is used  typically is"

>NameList nameList[]{
>    INAME(intVariable)
>}

>first of all, I just don't know what is doing that #x in the #define
>, I haven't found any reference to such a thing, the second is that the
>compiler always says at the INAME(whatever) that NI is not declared.

The #x is "build me a string with this argument" operator in the
preprocessor.  I.e. in your example it should expand to
   "intVariable"

I suspect that the compiler has hidden the name NI in the namespace for
the struct.  Try the above change, to where NI and NR are defined.

Also your macro needs some small changes
It has
#define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int));

It probably should be
#define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int), 000)

I.e. no ";", and you should have an initial value for the "vstatus"
field.  I wrote "000", but you need to replace that with some
value deduced by reading the code.

--------



Mon, 12 Jul 1999 03:00:00 GMT  
 About a namelist...with question

Quote:

> Hello,

> I have to modify a big program written by some smart guys, at
> least they are far smarter then I am, so I'm a little bit stucked
> with the following problem :

> it says :" ..while such service is standard in Fortran - the namelist
> there is no similar facility in C. We have therefore had to roll our
> own.."

> typedef struct {
>    char *vname;
>    void *vptr;
>    enum {NI, NR} vtype;
>    int vlen, vstatus;
> } NameList;

> #define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int));

> "the way it is used  typically is"

> NameList nameList[]{
>    INAME(intVariable)
> }

> first of all, I just don't know what is doing that #x in the #define
> , I haven't found any reference to such a thing, the second is that the
> compiler always says at the INAME(whatever) that NI is not declared.

> can someone help me out ?

This is a fairly standard way to solve the problem of printing out
information on a variable. You haven't posted the code for the function
that prints out a NameList, but I would guess that the NI and NR is a
flag to show real and integer. There may be hidden problems as the
printing out program will not be able to differentiate between signed
and unsigned values, also it assumes that all integer types are exact
multiples in size of an integer. Not always true even for short, and
definitely not for char in all general purpose machines.

Lets take this in parts

1) The #x stringifies the value x
2) Your #define is written wrong, NO semicolon at the end and match
   the braces (note pre-processor directives are ended by new line)
3) You need to learn more about the preprocessor directives - most
   compilers take the -E flag to output the file after pre-processing
   so this:-

       #define INAME(x) {#x, &x, NI, sizeof(x)/sizeof(int)}

       int main(void)
       {
          long foo;
          int bar;

          NameList nameList[] = {
               INAME(foo),
               INAME(bar)
          };

         return 0;
       }

    turns to this:-

       int main(void)
       {
          long foo;
          int bar;

          NameList nameList[] = {
                { "foo" , & foo , NI , sizeof ( foo ) / sizeof ( int ) },
                { "bar" , & bar , NI , sizeof ( bar ) / sizeof ( int ) }
          };

          return 0;
       }

4) Now that NI not being found - this is because NI is only available
   within scope FOR A C++ compiler! In C it is perfectly valid. If you
   want to compile this with a c++ compiler then declare the enum
   outside, to make its scope global ie:-

       typedef enum{NI,NR} Vtype;

       typedef struct {
               char *vname;
               void *vptr;
               Vtype vtype;
               int vlen, vstatus;
       } NameList;

5) However initialising with &foo is not legal, in C (though I believe
   it is in C++) and a true ANSI C compiler will reject it. (though
   most compilers have switches to let you do this if you want)

Read more about the pre-processor - if you can't find the use of # and
## as pre-processor directives in your C book then use it as firewood
and buy K&RII and a copy of the ANSI standard....

This is a case where understanding is important - don't just rely on
looking at the pre-processor output using the -E flag, understand what
it is doing and why.

I am guessing but I think this is all a way for the original program
writer to avoid learning to use a good de{*filter*} - as I assume that
the point is to enable the user to insert the ability to print out the
current state of the variables at any point in the program.

--
Douglas

---
=============================================================================

                                        Fax: +44 131-667 7209
============================= Mostly harmless ===============================



Tue, 13 Jul 1999 03:00:00 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. C/C++ implementation of FORTRAN namelists

2. scandir and struct dirent ***namelist

3. C Language Fortran Namelist Reader

4. c/c++ version of Fortran Namelist

5. namelists in C

6. question question question

7. This is a biztalk question but probably an easy question for you C# guru's

8. Non-Programming Question... experience question mostly

9. Question FAQ question

10. Not C program question, historical question

11. A question regarding FAQs question 12.2

12. Peer to peer board game - possible remoting question or design question

 

 
Powered by phpBB® Forum Software