Bug 18740 - Execution-time sizeof drops side effects
Summary: Execution-time sizeof drops side effects
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: 4.2.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks: 16989
  Show dependency treegraph
 
Reported: 2004-11-30 16:38 UTC by M Welinder
Modified: 2006-06-04 17:01 UTC (History)
2 users (show)

See Also:
Host: *-*-*
Target: *-*-*
Build: *-*-*
Known to work:
Known to fail:
Last reconfirmed: 2005-12-18 01:38:13


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description M Welinder 2004-11-30 16:38:29 UTC
The program below, which is a slight variation of a program from C99
section 6.5.3.4, contains an execution-time sizeof operator and its
argument should thus be evaluated.  Nevertheless, "i" in not incremented.

I would expect "i=1" to be printed.  I get "i=0".

(Sun's C compiler seems to do the same thing.)



#include <stdio.h>

size_t fsize3 (int n)
{
  int i = 0;
  char b[1][n+3];       // Variable length array.
  size_t s = sizeof (b[i++]);    // Execution time sizeof.
  printf ("i=%d\n", i);
  return s;
}

int main()
{
  size_t size;
  size = fsize3(10);
  return 0;
}
Comment 1 Wolfgang Bangerth 2004-11-30 22:24:50 UTC
That's not a bug. The standard says this: 
 
  5.3.3  Sizeof                                            [expr.sizeof] 
 
1 The  sizeof  operator  yields  the  number  of  bytes  in  the  object 
  representation of its operand.  The operand is either  an  expression, 
  which  is  not  evaluated,  or  a  parenthesized  type-id. 
 
W. 
Comment 2 Wolfgang Bangerth 2004-11-30 22:48:22 UTC
Actually, this requires more thought. I quoted from the C++ standard, but 
the bug is for C, and the problem lies here: the code is 
----------------- 
size_t fsize3 (int n) 
{ 
  int i = 0; 
  char b[1][n+3];       // Variable length array. 
  size_t s = sizeof (b[i++]); 
----------------- 
Indeed, b[0] is a VLA (or is it? maybe it's the GNU extension that looks 
so similar), and for that case, Morton pointed me correctly at 6.5.3.4/2 of 
the C99 standard, which has a special provision for this: 
  If the type of the operand is a variable length array type, the 
  operand is evaluated; otherwise the operand is not evaluated... 
 
Sorry for the confusion, 
 W. 
 
 
 
 
Comment 3 Eric Botcazou 2004-12-21 11:15:57 UTC
Reproducible on x86 and x86-64.
Comment 4 Richard Henderson 2004-12-21 13:39:42 UTC
Not a bug.  Sizeof *never* has side effects.
Comment 5 Richard Henderson 2004-12-21 13:43:06 UTC
I'm wrong.  What a stupid thing to do to the C language.
Someone should be smacked.
Comment 6 Mike Stump 2006-05-09 00:47:45 UTC
I have a fix for this.
Comment 7 mrs@gcc.gnu.org 2006-05-18 18:22:22 UTC
Subject: Bug 18740

Author: mrs
Date: Thu May 18 18:22:12 2006
New Revision: 113888

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=113888
Log:
	Fix up vla, vm and [*] sematics.

	PR c/18740
	PR c/7948
	PR c/25802
	* c-tree.h (struct c_arg_info): Add had_vla_unspec.
	(c_vla_unspec_p): Add.
	(c_vla_type_p): Add.
	* c-decl.c (struct c_scope): Add had_vla_unspec.
	(build_array_declarator): Add support for [*].
	(grokdeclarator): Likewise.
	(grokparms): Likewise.
	(get_parm_info): Likewise.
	* c-objc-common.c (c_vla_unspec_p): Likewise.
	* c-objc-common.h (LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P): Likewise.
	* c-parser.c (c_parser_typeof_specifier): Evaluate arguments to
	typeof when argument is a variably modified type not inside sizeof or alignof.
	(c_parser_direct_declarator_inner): Propagate errors.
	(c_parser_sizeof_expression): Add support for [*].
	* c-typeck.c (c_vla_type_p): Add.
	(composite_type): Add support for vla compositing.
	(comptypes_internal): Add support for vla compatibility.
	(c_expr_sizeof_expr): Evaluate vla arguments.
	* tree.c (variably_modified_type_p): Update comment for [*].

testsuite:
	* gcc.dg/c90-arraydecl-1.c: Update for vla, vm [*] fixups.
	* gcc.dg/vla-4.c: Add.
	* gcc.dg/vla-5.c: Add.
	* gcc.dg/vla-6.c: Add.

Added:
    trunk/gcc/testsuite/gcc.dg/vla-4.c
    trunk/gcc/testsuite/gcc.dg/vla-5.c
    trunk/gcc/testsuite/gcc.dg/vla-6.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-decl.c
    trunk/gcc/c-objc-common.c
    trunk/gcc/c-objc-common.h
    trunk/gcc/c-parser.c
    trunk/gcc/c-tree.h
    trunk/gcc/c-typeck.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/c90-arraydecl-1.c
    trunk/gcc/tree.c

Comment 8 Joseph S. Myers 2006-06-04 17:01:52 UTC
Fixed for 4.2.