Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

Does C correctly handle sizeof(...) and sizeof ... in this case?

In the following code, are the functions test and test2 equivalent?

typedef int rofl;

void test(void) {
    rofl * rofl = malloc(sizeof(rofl)); // Is the final rofl here the TYPE?
}

void test2(void) {
    rofl * rofl = malloc(sizeof *rofl); // Is the final rofl here the VARIABLE?
}

In other words:

  1. Does rofl in sizeof(rofl) correctly pick the rofl type because of the parentheses?
  2. Does rofl in sizeof *rofl correctly pick the rofl variable because of a lack of parentheses?

Note: This is a silly-looking example, but it can actually happen in practice that you have a type name that's the same as a variable name. Hence the question.

question from:https://stackoverflow.com/questions/47297871/does-c-correctly-handle-sizeof-and-sizeof-in-this-case

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In both cases, the last rofl is the variable name. A variable name is in scope as soon as it appears; and for the remainder of the current scope, that identifier in an ordinary context(*) always means the variable name.

The sizeof operator does not introduce any special cases for name lookup. In fact, there are no language constructs that will use the hidden meaning of an identifier.

In practice it is a good idea to not use the same identifier for a type and a variable name.


(*) There are three special contexts for identifiers: label names, structure tags, and structure members. But in all other contexts, all identifiers share a common name space: there are no distinct identifier name spaces for type names versus variable names versus function names etc.

Here is a contrived example:

typedef int A;      // "A" declared as ordinary identifier, meaning a type name

struct A { A A; };  // "A" declared as struct tag and member name -- OK as these are three different name spaces. Member type is "int"

A main()            // int main() - ordinary context
{
    struct A A();   // "A" declared as ordinary identifier, meaning a function name; hides line 1's A
    // A C;         // Would be error: ordinary A is a function now, not a typedef for int
    struct A B;     // OK, struct tags have separate name space
    A:+A().A;       // OK, labels and struct members have separate name space, calls function
    goto A;         // OK, label name space
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...