无符号类型的大按位左移

时间:2015-11-16 13:15:57

标签: c

类似于

<div>
    @(Html.Kendo().Grid<MvcApplication1.Models.Student>()
        .Name("grid")
        .Columns(columns =>
        {
            ..........
            ..........
            columns.Command(command => { command.Custom("checkBench1").Text("AM").Click("doCheckIn"); }).Title("Check in").Width(200);
        })
        .Events(events => events.DataBound("onDataBound"))
        ..........
        ..........
    )
</div>

<script> 
    function doCheckIn() {
        alert('a');
    }
    function onDataBound(arg) {
        $("#.k-grid-checkBench1").attr('href', 'javascript:void(0)');
    }
</script>

C中未定义的行为?

2 个答案:

答案 0 :(得分:10)

事实上,这种转变是未定义的行为。参见标准(C11,最终草案N1570,6.5.7p3):

  

"... If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined."

基本原理:如果移位计数>&gt; =参数的宽度,则移位操作在不同的CPU架构上的行为会有很大不同。通过这种方式,标准允许编译器生成最快的代码而无需关心边界效应。

注意:如果int宽于33位(例如64位),则情况会有所不同。 Reason是整数促销,它首先将uint32_t转换为int,因此使用(然后更大的)int值执行转换。对于此案例,这会将后转换为uint32_t转让,请参阅6.3.1.3第1,2段。但是,在大多数现代系统中,int不大于32位。

答案 1 :(得分:4)

这是(显然)未定义的行为。从C标准第6.5.7节(WG14 / N1256委员会草案 - 2007年第7章,ISO / IEC 9899:TC3 - 实际上是C99标准):

  
      
  1. 对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。

  2.   
  3. E1&lt;&lt;的结果E2E1左移E2位位置;腾出的位用零填充。如果E1具有无符号类型,则结果的值为E1×2 ^ E2,比结果类型中可表示的最大值减少一个模数。如果E1具有签名类型和非负值,并且E1×2 ^ E2在结果类型中可表示,那么这就是结果值;否则,行为未定义。

  4.   

Re 3,这表明它是未定义的行为,因为右操作数的值大于或等于提升的左操作数的宽度。

重新4,由于班次是无符号的,第一句适用:如果E1有无符号类型,则结果的值为E1×2 ^ E2,减少模数比结果类型中可表示的最大值多一个。这将(但对于3)表明结果为零。

我相信3将优先于4,所以它(毕竟)是未定义的。

奥拉夫的回答显示在C11下也是如此。