2

Is there an order of lookup in the namespaces namely, tag namespace and ordinary name space ? Consider the following code :

#include <stdio.h>

int main (void){

  typedef struct{ //This belongs to ordinary name space
    int min;
  } st;
  st myst;
  myst.min=6;
  struct myst{ // This belongs to tag name space
    int min;
  };
  myst.min=7;
  printf("%d\n%d\n",myst.min,myst.min);
  return 0;
}

Output

7

7

The compiler looks for the variable to print in the tag namespace first , I guess. I don't know if the lookup is even done for the same identifier in the ordinary namespace and if it is done I am clueless why it doesn't print it.

Community
  • 1
  • 1
0decimal0
  • 3,884
  • 2
  • 24
  • 39
  • *"The compiler looks for the variable to print in the tag namespace first"* - No it doesn't. You didn't specify a tag keyword. – StoryTeller - Unslander Monica Sep 20 '17 at 19:42
  • Not clear. A name is only searched in the name space you specify. Btw: There is no "tag name space". – too honest for this site Sep 20 '17 at 19:43
  • @StoryTeller tag keyword? didn't get you . `struct ` is the tag name . – 0decimal0 Sep 20 '17 at 19:48
  • No. `struct` is a kewyrod. `struct id` tells the compiler you want a tagged type and that it should look for `id` in the tag namespace. – StoryTeller - Unslander Monica Sep 20 '17 at 19:50
  • @StoryTeller ofcourse `struct` is a keyword and it comes in tag namespace if not defined using `typedef`. – 0decimal0 Sep 20 '17 at 19:52
  • `struct` doesn't come in the tag namespace... it's a keyword, not an identifier. Only identifiers go into namespaces. – StoryTeller - Unslander Monica Sep 20 '17 at 19:54
  • @StoryTeller yeah I meant the identifier defined using `struct`. – 0decimal0 Sep 20 '17 at 19:55
  • You favourite C book could tell better, but for `stuct tag` `tag` is the tag. `struct` introduces the structure-specifier. – too honest for this site Sep 20 '17 at 19:57
  • "*Strangely enough for me, it did print 6 the first time I compiled it*" -- it did not. I can imagine small variations on the code that would print 6, but the exact code you presented will always print 7, as shown. – John Bollinger Sep 20 '17 at 20:04
  • @JohnBollinger Yes , you are right I tweaked with the code and I didn't even notice it. Will edit the question. – 0decimal0 Sep 20 '17 at 20:06
  • @Olaf, you're right that there is no *single* "tag name space", but there are indeed three different ones, as C2011 6.2.3 pretty clearly states: "there are separate name spaces for various categories of identifiers, as follows [...] the tags of structures, unions, and enumerations (disambiguated by [...] the keywords struct, union, or enum)". But of course these are not namespaces in the C++ sense; the namespace to which a C identifier belongs is completely determined by the kind of thing it identifies. – John Bollinger Sep 20 '17 at 20:11
  • @JohnBollinger: As the question is tagged C, not C++, I think the context is clear. The standard expliciutly uses the term "name space", so it is fine. I'd say it is very well comparable to C++ namespaces, they are just bound to the type and there are no custom name spaces. However, nothing a good C book will not explain at the level asked. – too honest for this site Sep 20 '17 at 20:15

2 Answers2

7

There is no namespace lookup order in C. Only one namespace is ever considered for any particular identifier; it is determined by what kind of identifier is being looked up. Structure tags are one kind, with their own namespace; variable names are in the broader category of "ordinary identifiers", which have a separate namespace. There are other name spaces, too, but the compiler can always tell from context which one is relevant to any given identifier.

Thus, in your program, both uses of myst.min refer to the variable declared as st myst; and there isn't any second variable in the "tag" namespace (as you seem to have thought there would be).

You can see this for yourself by commenting out everything within main above myst.min = 7:

#include <stdio.h>

int main (void){
#if 0
  typedef struct{ //This belongs to ordinary name space
    int min;
  } st;
  st myst;
  myst.min=6;
#endif
  struct myst{ // This belongs to tag name space
    int min;
  };
  myst.min=7;
  printf("%d\n%d\n",myst.min,myst.min);
  return 0;
}

Attempting to compile this will produce a hard error:

test.c: In function ‘main’:
test.c:14:3: error: ‘myst’ undeclared (first use in this function)

What the struct myst declaration does is declare another type, which you can then use to declare variables. But it's not used for anything unless you actually do that. For instance

#include <stdio.h>

typedef struct { int min; } st;
struct myst { int min };
int main(void)
{
    // uses the typedef name 'st', in the ordinary namespace,
    // to declare the variable 'myst', also in the ordinary namespace
    st myst = { 6 };

    // uses the struct name 'myst', in the tag namespace,
    // to declare the variable 'myst2', in the ordinary namespace
    struct myst myst2 = { 7 };

    printf("%d %d\n", myst.min, myst2.min);
    return 0;
}

will print 6 7. This program also illustrates how myst, the variable, and myst, the struct tag, are indeed in two different namespaces and can be referred to independently.


(Thanks to John Bollinger for the new first paragraph. —ed)

zwol
  • 135,547
  • 38
  • 252
  • 361
  • Well actually defining same name will result in a conflict. Still confused about the order of lookup. – 0decimal0 Sep 20 '17 at 20:10
  • 2
    @0decimal0, there is no lookup order. Only one namespace is ever considered for any particular identifier; it is determined by what kind of identifier is being looked up. Structure tags are one kind, with their own namespace; variable names are in the broader category of "ordinary identifiers", which have a separate namespace. There are other name spaces, too, but the compiler can always tell from context which one is relevant to any given identifier. – John Bollinger Sep 20 '17 at 20:15
  • Thanks @JohnBollinger , I get it now. – 0decimal0 Sep 21 '17 at 07:20
  • @JohnBollinger May I copy your comment into the text of my answer? – zwol Sep 21 '17 at 14:30
  • Sure, @zwol, I have no objection. – John Bollinger Sep 21 '17 at 15:06
3

C namespaces are completely disjoint. Each identifier is searches ony in one namespace. For example:

  • Identifiers that follow structand union keywords are searched in the tag namespace
  • Identifiers that follow the goto keyword are searched in the label namespace
  • Identifiers that follow . or -> symbols are searched in their structure or union member namespace (each structure and union has its own member namespace; type of the preceding expression determines which one to search)
  • Other identifiers are searched in the ordinary namespace.

There is no lookup order. The (unique) namespace to search is completely determined by the context.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243