¥È¥Ã¥×   ÊÔ½¸ Åà·ë º¹Ê¬ ÍúÎò źÉÕ Ê£À½ ̾Á°Êѹ¹ ¥ê¥í¡¼¥É   ¿·µ¬ °ìÍ÷ ¸¡º÷ ºÇ½ª¹¹¿·   ¥Ø¥ë¥×   ºÇ½ª¹¹¿·¤ÎRSS

¥á¥ó¥Ð¡¼/y-takata/misc/n=n++;

Last-modified: 2009-05-08 (¶â) 19:07:30

n = n++;

¤Þ¤¨¤ª¤­

n = n++; ¤È¤¤¤¦ÂåÆþʸ¤ÎÏäòMÀèÀ¸¤«¤éʹ¤¤¤Æ¡¢µ¤¤Ë¤Ê¤Ã¤¿¤Î¤ÇÄ´¤Ù¤Æ¤ß¤¿¡£

¼Â¤ÏMÀèÀ¸¤¬¸À¤Ã¤Æ¤ª¤é¤ì¤¿¤Î¤Ï°Ê²¼¤Î¤è¤¦¤Ê¥³¡¼¥É¤Î¤³¤È¤Ç¡¢¤³¤ì¤Ê¤éÊ̤ËÌäÂê¤Ê¤¤¡£¡Ê¾¯¤Ê¤¯¤È¤â²ò¼á¤Ë¤Ïº¤¤é¤Ê¤¤¡£¡Ë

class Some {
    int n;
    void foo(int n) {
        this.n = n++;
    }
}

ËÜÂê

ʸ»úÄ̤ê n = n++; ¤È¤¤¤¦ÂåÆþʸ¤À¤È¤É¤¦¤Ê¤ë¤Î? ¤È¤¤¤¦¤Î¤¬º£²ó¤ÎÌäÂê¡£¤Ä¤Þ¤ê¡¢

int n = 0;
n = n++;

¤È¤¤¤¦¥³¡¼¥É¤ò¹Í¤¨¤ë¤È¡¢

  1. ¼° n++ ¤ÎÃÍ¤Ï 0 ¤Ê¤Î¤Ç¡¢ÂåÆþ±é»»¤Ë¤è¤Ã¤Æ n ¤Ë 0 ¤¬ÂåÆþ¤µ¤ì¤ë¡£
  2. ++±é»»»Ò¤Ë¤è¤ê¡¢n ¤¬¥¤¥ó¥¯¥ê¥á¥ó¥È¤µ¤ì¤ë¡£

¤È¤¤¤¦2¤Ä¤Î½èÍý¤¬¹Ô¤ï¤ì¤ë¤Ï¤º¤À¤±¤ì¤É¤â¡¢½ç½ø¼¡Âè¤Ç·ë²Ì¤ÏÊѤï¤ë¡£1¢ª2¤Ê¤é¼Â¹Ô¸å¤Î n ¤Ï1¤Ë¤Ê¤ë¤·¡¢2¢ª1¤Ê¤é n ¤Ï0¤Ë¤Ê¤ë¡£

n = n + 1; ¤È¤¤¤¦½ñ¤­Êý¤È n++; ¤È¤¤¤¦½ñ¤­Êý¤ò½¬¤Ã¤¿¿Í¤¬¡¢¤³¤ó¤¬¤é¤¬¤Ã¤Æ(?) n = n++; ¤È½ñ¤¤¤¿¡¢¤È¤¤¤¦Îã¤Ï²¿²ó¤«¸«¤¿¤³¤È¤¢¤ë¡£¤½¤Î¤È¤­»È¤Ã¤Æ¤¿ Microsoft C/C++ Compiler ¤À¤È¡¢Æä˷ٹð¤Ï¤Ê¤¯¡¢·ë²Ì¤Ï n++; ¤È½ñ¤¤¤¿¤Î¤ÈƱ¤¸¡Ên ¤¬¥¤¥ó¥¯¥ê¥á¥ó¥È¤µ¤ì¤ë¡Ë¤À¤Ã¤¿¡£¡Ê½ñ¤¤¤¿¿Í¤¿¤Á¤â¥¤¥ó¥¯¥ê¥á¥ó¥È¤Î¤Ä¤â¤ê¤Ç½ñ¤¤¤Æ¤¤¤ë¤Î¤Ç¡¢´Ö°ã¤¤¤Ëµ¤¤Å¤«¤Ê¤«¤Ã¤¿¡£¡Ë

K&R

K&R*1¤Ë¤Ï¡¢°­¤¤Îã¤È¤·¤Æ a[i] = i++; ¤¬½Ð¤Æ¤¯¤ë¡Êa[i] ¤Î i ¤ÎÃͤϽèÍý·Ï°Í¸¡Ë¡£¤Ê¤é¡¢n = n++; ¤â°­¤¤Îã¤Ê¤ó¤Ç¤·¤ç¤¦¤Í? ¤¿¤Ö¤ó¡£

GCC

GCC¤À¤È¤É¤¦¤«? ¤È¤¤¤¦¤È¡¢·ë²Ì n ¤¬¥¤¥ó¥¯¥ê¥á¥ó¥È¤µ¤ì¤ë¤Î¤ÏƱ¤¸¡Ê»î¤·¤¿¤Î¤Ï powerpc-apple-darwin8-gcc-4.0.1 ¤È i386-redhat-linux-gcc-4.1.2¡Ë¡£

¤Ç¡¢-Wsequence-point¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤ë¤È¡¢

warning: operation on 'n' may be undefined

¤È¤¤¤¦·Ù¹ð¤¬½Ð¤ë¤è¤¦¤Ë¤Ê¤ë¡Ê¥«¥·¥³¥¤¡Ë¡£

man¥Ú¡¼¥¸¤Î -Wsequence-point ¤Î¹à¤ò¸«¤ë¤È¡¢

(ά)

Examples of code with undefined behavior are "a = a++;", "a[n] = b[n++]" and "a[i++] = i;". Some more complicated cases are not diagnosed by this option, and it may give an occasional false positive result, but in general it has been found fairly effective at detecting this sort of problem in programs.

(ά)

¤È¤¤¤¦¤³¤È¤Ç¡¢n = n++; ¤Ï undefined behavior ¤Ê¥³¡¼¥É¤È¤Î¤³¤È¡£

Java

¤¸¤ã¤¢ Java ¤Ï? ¤È¤¤¤¦¤È¡¢¤³¤ì¤¬¥¨¥é¡¼¤¸¤ã¤Ê¤¤¤Î¤À¤Ê¡£¡Ê°Õ³°¤¸¤ã¤Ê¤¤? ¤½¤¦?¡Ë

int n = 0;
n = n++;
System.out.println("n = " + n);

¤È¤¤¤¦¥³¡¼¥É¤Ï¤Á¤ã¤ó¤È¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤ë¡£¤Ç¡¢·ë²Ì¤Ï n = 0 ¤Èɽ¼¨¤µ¤ì¤ë¡£¤Ä¤Þ¤ê¡¢¾å¤Î¤Û¤¦¤Ë½ñ¤¤¤¿2¢ª1¤Î½ç¡¢¤È¤¤¤¦¤³¤È¤Ë¡£

¸À¸ì»ÅÍÍ

Java¸À¸ì»ÅÍÍ*2¤Ç¤Ï¤É¤¦¤Ê¤Ã¤Æ¤ó¤Î? ¤È¸«¤Æ¤ß¤ë¤È¡¢¡Öɾ²Á½ç½ø¡×¤È¤¤¤¦Àá(¡ø15.7)¤Ë¤´¤Á¤ã¤´¤Á¤ã½ñ¤¤¤Æ¤¢¤ë¡£

n = n++; ¤Î²ò¼á¤Ï¡ÖEvaluate Operands before Operation¡×(¡ø15.7.2)¤Î¸¶Â§¤Ë½¾¤¨¤Ð¤è¤¤¤Î¤Ç¤·¤ç¤¦¤Í? ¤Ä¤Þ¤ê¡¢ÂåÆþ±é»»¤è¤êÀè¤Ë±¦ÊÕ¤¬´°Á´¤Ëɾ²Á¤µ¤ì¤ë(fully evaluated)¡¢¤È¡£¡Ö´°Á´¤Ëɾ²Á¤µ¤ì¤ë¡×¤Ã¤Æ²¿? ¤È¸À¤¦¤È¡¢¡ø15.7.1¤ÎËÜʸ¤«¤é»¡¤¹¤ë¤Ë¡¢ÉûºîÍѤâÁ´Éô¼Â¹Ô¤µ¤ì¤ë¡¢¤È¤¤¤¦°ÕÌ£¤ß¤¿¤¤¡£

¡Ön = a++; ¤Ï¤è¤¯¤Æ n = n++; ¤Ï¤À¤á¡×¤È¤«¸À¤¤½Ð¤¹¤Èµ¬Â§¤¬Ê£»¨¤Ë¤Ê¤ë¤·¡¢Âå¤ï¤ê¤Ë°ÕÌ£ÏÀ¤Î¼«Í³ÅÙ¤ò¤Ê¤¯¤·¤È¤±¤Ð¡Êrun anywhereŪ¤Ë¤Ï¡ËÉÔÅÔ¹ç¤Ê¤¤¤Ç¤·¤ç? ¤Æ¤³¤È¤«¡£

¤È¸À¤¦¤³¤È¤Ï

¤¸¤ã¤¢ a[i] = i++; ¤ä a[i++] = i; ¤âok¤Ê¤ï¤±¤Í? ¤È¤¤¤¦¤³¤È¤Ç¼Â¸³¡£

int[] a = new int[] { 0, 0, 0, 0, 0 };
int i = 1;
a[i]   = i++;  // (*1)
a[i++] = i;    // (*2)
for (int j = 0; j < a.length; j++) {
    System.out.print(a[j] + " ");
}
System.out.println();

ÌäÂê¤Ê¤¯¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤ë¡£·ë²Ì¤Ï 0 1 3 0 0¡£

= ¤Ë¤Ä¤¤¤Æ¤â¡ÖEvaluate Left-Hand Operand First¡×(¡ø15.7.1)¤Î¸¶Â§¤Ç¡¢º¸ÊÕ¤òÀè¤Ëɾ²Á¤¹¤ë¤ï¤±¤Ç¤¹¤Ê? ¾å¤Î¥³¡¼¥É¤Î(*1)¤Ç¤Ï a[1] ¤Ë 1 ¤¬ÂåÆþ¤µ¤ì¡¢i ¤Ï 2 ¤Ë¤Ê¤ë¡£(*2)¤Ç¤Ï a[2] ¤Ë¥¤¥ó¥¯¥ê¥á¥ó¥È¸å¤Î i ¤¬ÂåÆþ¤µ¤ì¤ë¡£

¤ª¤Þ¤±¤Î¼Â¸³

¤³¤Î¸À¸ì»ÅÍͽñ¤È¤«¡ÈThe Java Programming Language*3¡É¤È¤«¤è¤¯¸«¤ë¤È¡¢n = n++; ¤è¤ê¤¨¤²¤Ä¤Ê¤¤Îã¤â¤¤¤í¤¤¤í¤È¡Ä¡£

²¼µ­¤ÏThe Java Programming Language¤Î¡ø9.2.1¤ÎÎã¡£

int i = 16;
System.out.println(++i + " " + i++ + " " + i);

¡Ä¤Ï¤¤¤Ï¤¤¡¢JavaŪ¤Ë¤Ïok¤Ê¤ó¤Ç¤·¤ç? ¤è¤¯¤ï¤«¤ê¥Þ¥·¥¿¡£(-.-) ¤Á¤Ê¤ß¤Ë 17 17 18 ¤Èɽ¼¨¤µ¤ì¤ë¤Î¤¬Àµ²ò¡£

¤â¤Á¤í¤ó C ¤Ç¤Ï½èÍý·Ï°Í¸¤Î¤Ï¤º¡Ä¡¢¤È¤¤¤¦¤³¤È¤Ç»î¤·¤Æ¤ß¤ë¡£Ê¸»úÎóÏ¢·ë±é»»»Ò¤¬¤Ê¤¤¤Î¤Ç¤½¤Ã¤¯¤ê¤Ë¤Ï¤Ç¤­¤Ê¤¤¤¬¡¢²¼¤Î¤è¤¦¤Ê¥³¡¼¥É¤À¤È¡Ä¡£

int i = 16;
printf("%d %d %d\n", ++i, i++, i);

K&R¤Ë¤â»÷¤¿Î㤬¡Ö°­¤¤Îã¡×¤È¤·¤Æµó¤¬¤Ã¤Æ¤¤¤ë¡Ê°ú¿ô¤Îɾ²Á½ç½ø¤Ï½èÍý·Ï°Í¸¡Ë¡£¼Â¹Ô·ë²Ì¤Ï°Ê²¼¤ÎÄ̤ꡣ

powerpc-apple-darwin8-gcc-4.0.118 17 18
i386-redhat-linux-gcc-4.1.218 16 18

2ÈÖÌܤÀ¤±¾®¤µ¤¤Ãͤˤʤë¤Î¤¬¤Á¤ç¤Ã¤È°Õ³°¡£

º£ÅÙ¤Ï sprintf ¤È strcat ¤òÁȤ߹ç¤ï¤»¤Æʸ»úÎóÏ¢·ë±é»»¤òÌÏÊ路¤Æ¤ß¤ë¤È¡Ä¡Ê²¼¤Î¥³¡¼¥É¡Ë¡£

#include <stdio.h>
#include <string.h>
char *tostr(int i) {
    static char buf[3][256];
    static int bufc = 0;
    sprintf(buf[bufc], "%d ", i);
    return buf[bufc++];
}
int main() {
    int n = 16;
    printf("%s\n", strcat(strcat(tostr(++n), tostr(n++)), tostr(n)));
    return 0;
}

·ë²Ì¤Ï°Ê²¼¤ÎÄ̤ꡣpowerpc¤Ïº¸°ú¿ôÍ¥Àè¡¢i386¤Ï±¦°ú¿ôÍ¥Àè¡¢¤Î¤è¤¦¤Ê·ë²Ì¡£

powerpc-apple-darwin8-gcc-4.0.117 17 18
i386-redhat-linux-gcc-4.1.218 16 16

·ëÏÀ

n = n++; ¤È¤¤¤¦Ê¸¤Ï¡¢

  • Java¤Ç¤ÏÀµ¤·¤¤Ê¸¡Ê¤Ç¤â n ¤ÎÃͤÏÊѲ½¤·¤Ê¤¤¤Î¤Ç̵°ÕÌ£¡Ë
  • C¤Ç¤Ï¿¶¤ëÉñ¤¤¤Ï½èÍý·Ï°Í¸¡Ê¤Ç¤â¥¤¥ó¥¯¥ê¥á¥ó¥È¤µ¤ì¤ë¾ì¹ç¤¬Â¿¤¤?¡Ë
  • GCC 4 ¤Ç -Wall ¤ò¤Ä¤±¤ì¤Ð·Ù¹ð¤¬É½¼¨¤µ¤ì¤ë

*1 ¥«¡¼¥Ë¥Ï¥ó, ¥ê¥Ã¥Á¡¼: ¥×¥í¥°¥é¥ß¥ó¥°¸À¸ìC, Âè2ÈÇ, ÀÐÅÄÌõ, p.66, ¶¦Î©½ÐÈÇ, 1989.
*2 The Java Language Specification, Third Edition, http://java.sun.com/docs/books/jls/
*3 K.Arnold, J.Gosling, and D.Holmes: The Java Programming Language, Fourth Edition, Addison-Wesley, 2006.