从冒泡程序意外输出MSVC VS TCC [英] Unexpected output from Bubblesort program with MSVC vs TCC

查看:166
本文介绍了从冒泡程序意外输出MSVC VS TCC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个朋友发送此code给我,说如预期它不工作:

One of my friends sent this code to me, saying it doesn't work as expected:

#include<stdio.h>

void main()
{
    int a [10] ={23, 100, 20, 30, 25, 45, 40, 55, 43, 42};
    int sizeOfInput = sizeof(a)/sizeof(int);
    int b, outer, inner, c;
    printf("Size is : %d \n", sizeOfInput);

    printf("Values before bubble sort are  : \n");
    for ( b = 0; b &lt; sizeOfInput; b++)
        printf("%d\n", a[b]);

    printf("End of values before bubble sort... \n");

    for ( outer = sizeOfInput; outer &gt; 0; outer-- )
    {
        for (  inner = 0 ; inner &lt; outer ; inner++)
        {
        printf ( "Comparing positions: %d and %d\n",inner,inner+1);
        if ( a[inner] &gt; a[inner + 1] )
        {
                int tmp = a[inner];
                a[inner] = a [inner+1];
            a[inner+1] = tmp;
            }
        }
        printf ( "Bubble sort total array size after inner loop is %d :\n",sizeOfInput);
        printf ( "Bubble sort sizeOfInput after inner loop is %d :\n",sizeOfInput);
    }
    printf ( "Bubble sort total array size at the end is %d :\n",sizeOfInput);
    for ( c = 0 ; c &lt; sizeOfInput; c++)
        printf("Element: %d\n", a[c]);
}


我使用Micosoft Visual Studio的命令行工具编译这样的Windows XP计算机上。
CL / EHSC bubblesort01.c

I am using Micosoft Visual Studio Command Line Tool for compiling this on a Windows XP machine. cl /EHsc bubblesort01.c

我的朋友得到一个恐龙的机器上正确的输出(code使用TCC编译的存在)。

我的产量出乎意料。阵列神秘增长的大小,在两者之间。

My friend gets the correct output on a dinosaur machine (code is compiled using TCC there).
My output is unexpected. The array mysteriously grows in size, in between.

如果您使得可变sizeOfInput改变为sizeOfInputt改变code,它赋予了预期效果

If you change the code so that the variable sizeOfInput is changed to sizeOfInputt, it gives the expected results!

微软的Visual C ++开发人员中心做一个搜索没有给出任何结果sizeOfInput

A search done at Microsoft Visual C++ Developer Center doesn't give any results for "sizeOfInput".

我不是一个C / C ++专家,好奇地找出为什么出现这种情况 - 任何C / C ++的专家对这个谁可以提供一些线索?

无关注:我认真考虑重写整个code使用快速排序或在这里张贴之前归并排序的。但是,毕竟,它不臭皮匠排序...

I am not a C/C++ expert, and am curious to find out why this happens - any C/C++ experts who can "shed some light" on this?
Unrelated note: I seriously thought of rewriting the whole code to use quicksort or merge sort before posting it here. But, after all, it is not Stooge sort...

编辑:我知道code是不正确(读取超出了最后一个元素),但我很好奇,为什么变量名有差别

I know the code is not correct (it reads beyond the last element), but I am curious why the variable name makes a difference.

推荐答案

像<一个href=\"http://stackoverflow.com/questions/4575697/unexpected-output-while-using-microsoft-visual-studio-2008-ex$p$pss-edition-c/4575724#4575724\">interjay's答复中提到,一旦你进入未定义行为全盘皆输。但是,当你说这仅仅是重命名变量改程序的行为,我得到了好奇发生了什么事情(未定义或没有)。

Like interjay's answer mentioned, once you get into undefined behavior all bets are off. However, when you said that merely renaming the variable changed the behavior of the program, I got curious about what was going on (undefined or not).

首先,我不相信重命名变量会改变编译器的输出(所有其他条件相同),但肯定不够 - 当我尝试了,我很惊讶地看到你描述的到底是什么

First, I didn't believe that renaming the variable would change the compiler's output (all other things being equal), but sure enough - when I tried it, I was surprised to see exactly what you described.

因此​​,我不得不编译器转储为code这是生成源文件的每个版本的组件,跑的比较。下面是我在它是如何布局的局部变量的编译器描述中发现:

So I had the compiler dump the assembly for the code it was generating for each version of the source file, and ran a comparison. Here's what I found in the compilers description of how it was laying out the local variables:

    ***** test.sizeOfInput.cod
    _c$ = -56                    ; size = 4
    _b$ = -52                    ; size = 4
    _inner$ = -48                ; size = 4
    _a$ = -44                    ; size = 40
>>> _sizeOfInput$ = -4           ; size = 4
    _main   PROC
    ***** test.sizeOfInputt.cod
    _c$ = -56                    ; size = 4
>>> _sizeOfInputt$ = -52         ; size = 4
    _b$ = -48                    ; size = 4
    _inner$ = -44                ; size = 4
    _a$ = -40                    ; size = 40
    _main   PROC
    *****

什么你会注意到的是,当变量被命名为 sizeOfInput ,他在编译器比阵列更高的地址地方,它 A (刚刚过去的数组的结束),并且当变量被命名为 sizeOfInputt 它把它在比阵列 A低地址而不是刚刚过去的数组的末尾。这意味着,在评选的变量 sizeOfInput 构建,当你修改发生不确定的行为 A [10] 正在改变 sizeOfInput 的价值。在使用的名称构建 sizeOfInputt ,因为该变量不是在数组的末尾,写 A [10] 象垃圾一样清除别的东西。

What you'll notice is that when the variable is named sizeOfInput, he compiler places it at a higher address than array a (just past the end of the array), and when the variable is named sizeOfInputt it places it at a lower address than array a instead of just past the end of the array. That means that in the build that has the variable named sizeOfInput, the undefined behavior that occurs when you modify a[10] is changing the value of sizeOfInput. In the build that uses the name sizeOfInputt, since that variable isn't at the end of the array, the write to a[10] trashes something else.

至于为什么编译器会有所不同铺陈变量时的一种看来微不足道的途径之一,更改名称 - 我不知道

As to why the compiler would lay out the variables differently when the name of one changes in an apparently insignificant way - I have no idea.

但是,这就是为什么你不应该对局部变量的布局数(或pretty太多的变量,但你可以结构元素的布局顺序计数),而当谈到为什么一个很好的例子未定义的行为,它的工作原理我的机器上不剪,以证明什么工作的。

But this is a good example of why you shouldn't count on the layout of local variables (or pretty much any variables, though you can count on the layout order of struct elements), and why when it comes to undefined behavior, "it works on my machine" doesn't cut it as proof that something works.

这篇关于从冒泡程序意外输出MSVC VS TCC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆