Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lvalue-to-rvalue conversion of an array in ISO C

C++ ANSI ISO IEC 14882 2003 Annex C.1 (page 668):

Change: The result of a conditional expression, an assignment expression, or a comma expression may bean lvalue
Rationale: C + + is an object-oriented language, placing relatively more emphasis on lvalues. For example, functions may return lvalues.
Effect on original feature: Change to semantics of well-defined feature. Some C expressions that implicitly rely on lvalue-to-rvalue conversions will yield different results. For example,

char arr[100];
sizeof(0, arr)

yields 100 in C + + and sizeof(char*) in C.
...

I was reading this just today and I remembered that a couple of months a go a friend of mine proposed a problem wchich was to write a function that would return 0 if it were compiled with C++ and 1 if it were compiled with C. I solved it taking advantage of the fact that in C a struct was in the outer scope. So, considering this new information, I decided that this would be another solution to the above problem, which I tried on Microsoft Visual Studio 2008, but regardless of whether it is compiled as C or C++ code sizeof(0, arr) always yields 4. So 2 questions:

1.What is ISO C? Is it the current C standard? Is it the only one (I hear C is rapidly evolving) 2. Is this a microsoft C++ bug?

TIA

Edit: Sorry got mixed up with the output and edited it:

like image 687
Armen Tsirunyan Avatar asked Oct 17 '10 12:10

Armen Tsirunyan


2 Answers

ISO C is the C standard. The current one is C99 but C1x is right around the corner. If by rapid, you mean a new standard every decade or so, then yes, it is rapidly evolving :-)

Section 6.5.3.4/3 of ISO C99 states:

When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

When applied to an operand that has array type, the result is the total number of bytes in the array.

like image 191
paxdiablo Avatar answered Sep 20 '22 12:09

paxdiablo


Or just microsoft's C is not ISO C but some other standard C (if there exists any).

Microsoft Visual C still supports C89 [only] whereas other compilers like gcc/clang etc support C99 too which is the current Standard.

C99 [Section 6.5.17/2] says

The left operand of a comma operator is evaluated as a void expression; there is a sequence point after its evaluation. Then the right operand is evaluated; the result has its type and value.95

Thus the result of sizeof (0,arr) would be sizeof(char*)[due to the implicit lvalue to rvalue conversion /automatic decay to pointer type] not 100*sizeof(char)

sizeof(arr) would have given 100*sizeof(char) from 6.5.3.4/3

95) A comma operator does not yield an lvalue.


decided that this would be another solution to the above problem, which I tried on Microsoft Visual Studio 2008, but regardless of whether it is compiled as C or C++ code sizeof(0, arr) always yields 4.

C++03 [5.18/1] Comma Operator

The type and value of the result are the type and value of the right operand; the result is an lvalue if its right operand is.

So sizeof(0, arr) = sizeof (arr) and which would be equal to 100* sizeof(char) and not = sizeof(char*).

So MSVC++ is giving incorrect result (in case of C++ code).

like image 43
Prasoon Saurav Avatar answered Sep 21 '22 12:09

Prasoon Saurav