1

Should the following code produce the compile time error: "jump into scope of identifier with variably modified type"? I can understand why the C99 Standard has this constraint if the data is dynamically reserved on the stack. But I cannot understand what the problem is when the declaration results from a simple cast to a dynamically allocated block from the heap.

void ShowVariablyModifiedTypeBug(void)
{
    int rowCount = 2;
    int colCount = 5;
    int elementCount = rowCount * colCount;

    void *dataPtr = malloc(sizeof(int) * elementCount);
    if (!dataPtr) goto exit;
    int (*dataArr)[colCount] = (int (*)[colCount])dataPtr;

exit:
    return;
}
user1261695
  • 41
  • 1
  • 5
  • No, this is not a duplicate of that question. In that case the data has allocated on the stack. And all the answers indicated that that is why the c standard was written with this constraint. However, here the data is allocated on the heap. Thus, the justifications claimed in those responses are not valid here. – user1261695 Jul 16 '14 at 03:44
  • The second answer to that SO question, http://stackoverflow.com/a/20654413/434551, clearly cites the standard indicating why your code is not standards compliant. – R Sahu Jul 16 '14 at 04:32
  • @user1261695 The pointer is still on the stack. – anthony sottile Jul 16 '14 at 04:53
  • Irrelevant. If the expression "int (*dataArr)[colCount] = (int (*)[colCount])dataPtr;" is removed, then the error goes away, but the pointer is still on the stack. – user1261695 Jul 16 '14 at 11:54
  • The addition of variable-length arrays to C99 adds a number of quirks and complexities to the language (e.g. turning `typedef` into an executable statement!). It would be difficult to characterize those situations where it would be possible to jump into the scope of a variably-modified type; since such constructs are generally not very useful, it's simpler to forbid them altogether. – supercat Jul 16 '15 at 20:32

1 Answers1

1

As stated in R. Sahu's comment, the SO question is clearly not compliant with the standard.

C99 standard, paragraph 6.8.6.1

Constraints

[...] A goto statement shall not jump from outside the scope of an identifier
having a variably modified type to inside the scope of that identifier.

And as outlined in https://stackoverflow.com/a/20654413/434551, the error: "jump into scope of identifier with variably modified type" can be avoided by the creation of a sub-scope:

void ShowVariablyModifiedTypeBug(void)
{
    int rowCount = 2;
    int colCount = 5;
    int elementCount = rowCount * colCount;

    void *dataPtr = malloc(sizeof(int) * elementCount);
    if (!dataPtr) goto exit;

    {
    int (*dataArr)[colCount] = (int (*)[colCount])dataPtr;
    }

exit:
    return;
}
Community
  • 1
  • 1
Mahonri Moriancumer
  • 5,993
  • 2
  • 18
  • 28
  • Adding to this, 6.7.5#3 describes how `dataArr` is in fact an identifier with variably modified type: "If, in the nested sequence of declarators in a full declarator, there is a declarator specifying a variable length array type, the type specified by the full declarator is said to be *variably modified*. Furthermore, any type derived by declarator type derivation from a variably modified type is itself variably modified" – M.M Jul 16 '14 at 04:57
  • Clearly, the **C99 standard** forbids this construct. But what are the justifications for it? In the other post, the justification was that data could be left on the stack. Here that is not possible. So what is the justification for forbidding such code? I do not understand when this could be a problem. Also, an alternative work-around is to swap the order of `if (!dataPtr) goto exit;` and `int (*dataArr)[colCount] = (int (*)[colCount])dataPtr;` In this case we would be jumping within (not into) the scope of dataArr. – user1261695 Jul 16 '14 at 13:37
  • Everyone is missing the point of the question. The question is not "Why doesn't this code compile" but rather "Why does the C99 standard forbid this code?". – user1261695 Jul 16 '14 at 16:48