小编Lyi*_*Sky的帖子

为什么这段代码会抛出'Collection was modified',但是当我在它之前迭代一些东西时,它却没有?

var ints = new List< int >( new[ ] {
    1,
    2,
    3,
    4,
    5
} );
var first = true;
foreach( var v in ints ) {
    if ( first ) {
        for ( long i = 0 ; i < int.MaxValue ; ++i ) { //<-- The thing I iterate
            ints.Add( 1 );
            ints.RemoveAt( ints.Count - 1 );
        }
        ints.Add( 6 );
        ints.Add( 7 );
    }
    Console.WriteLine( v );
    first = false;
}
Run Code Online (Sandbox Code Playgroud)

如果你注释掉内部for循环,它会抛出,显然是因为我们对集合进行了更改.

现在,如果你取消注释,为什么这个循环允许我们添加这两个项目?它需要一段时间才能运行半分钟(在奔腾CPU上),但它不会抛出,而有趣的是它输出:

图片

这有点预期,但它表明我们可以改变,它实际上改变了收藏.任何想法为什么会发生这种行为?

c# collections

102
推荐指数
1
解决办法
2793
查看次数

如何在没有运行时成本的情况下基于断言来指导GCC优化?

我有一个宏在我的代码中使用,在调试模式下:

#define contract(condition) \
    if (!(condition)) \
        throw exception("a contract has been violated");
Run Code Online (Sandbox Code Playgroud)

...但在发布模式下:

#define contract(condition) \
    if (!(condition)) \
        __builtin_unreachable();
Run Code Online (Sandbox Code Playgroud)

这样做的原因assert()是,在发布版本中,由于UB传播,编译器可以大量优化代码.

例如,使用以下代码进行测试:

int foo(int i) {
    contract(i == 1);
    return i;
}

// ...

foo(0);
Run Code Online (Sandbox Code Playgroud)

...在调试模式下抛出异常,但return 1;在释放模式下为无条件生成程序集:

foo(int):
        mov     eax, 1
        ret
Run Code Online (Sandbox Code Playgroud)

条件以及依赖它的一切都已经过优化.

我的问题出现在更复杂的条件下.当编译器无法证明条件没有副作用时,它不会将其优化出来,与不使用合同相比,这是一个严重的惩罚.

有没有办法表明合同中的条件没有副作用,所以总是优化出来?

c++ optimization gcc assert compiler-optimization

22
推荐指数
3
解决办法
1104
查看次数

这是什么?在C#中意味着什么?

从项目Roslyn,文件src\Compilers\CSharp\Portable\Syntax\CSharpSyntaxTree.cs在线路446有:

using (var parser = new InternalSyntax.LanguageParser(lexer, oldTree?.GetRoot(), changes))
Run Code Online (Sandbox Code Playgroud)

是什么?.呢?

它检查oldTree是什么null,如果不是那么它正在运行GetRoot方法,如果没有那么它返回什么?这是我的第一个假设(可能是错误的),但我无法继续前进.(确认,和/或回答新问题)

我用Google搜索What is ?. C#,没有任何相关内容,就好像它忽略了我的?.(?)

c# operators

15
推荐指数
1
解决办法
655
查看次数

这个26KB可执行文件中存储了什么?

使用以下代码编译此代码-O3:

#include <iostream>
int main(){std::cout<<"Hello World"<<std::endl;}
Run Code Online (Sandbox Code Playgroud)

导致文件长度为25,890字节.(由GCC 4.8.1编制)

编译器是否只能存储两个调用write(STDOUT_FILENO, ???, strlen(???));,存储write内容,存储字符串,并将它写入磁盘?它应该导致EXE的长度低于1,024我估计的字节数.

在汇编结果中编译hello world程序以17字节为单位:https://stackoverflow.com/questions/284797/hello-world-in-less-than-17-bytes,表示实际代码长度为5个字节.(字符串是Hello World\0)

除了实际main和它调用的功能外,EXE还存储了什么?

注意:此问题也适用于MSVC.


编辑:
许多用户指出iostream是罪魁祸首,所以我测试了这个假设并用相同的参数编译了这个程序:

int main( ) {
}
Run Code Online (Sandbox Code Playgroud)

得到23,815字节后,这个假设被驳斥了.

c++ windows gcc visual-c++

15
推荐指数
2
解决办法
999
查看次数

为什么第二次迭代大量字节的速度明显变慢?以及如何解决它?

这段代码:

#include <memory>
#include <time.h>
#include <chrono>
#include <thread>
#include <stdio.h>
#include <stdlib.h>

void Test( ) {
#define current_milliseconds std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now( ).time_since_epoch( ) ).count( )
    int *c = ( int* )malloc( 1024 * 1024 * 1024 );
    int result = 0;
    auto millis = -current_milliseconds;
    //clock_t timer = -clock( );
    for ( int i = 0 ; i < 1024 * 1024 * 256 /* 1024 / 4 */; ++i )
        result += c[ i ];
    millis += current_milliseconds;
    printf( …
Run Code Online (Sandbox Code Playgroud)

c++ performance

13
推荐指数
1
解决办法
638
查看次数

为什么GCC明确表示它会减慢程序时,会在O2/O3上启用优化?

引用自https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html:

-falign-标签

-falign-标签=正

将所有分支目标对齐为二次幂边界,跳过n个字节,如-falign-functions.此选项可以轻松地使代码变慢,因为它必须在通常的代码流中到达分支目标时插入虚拟操作.

-fno-align-labels和-falign-labels = 1是等效的,表示标签未对齐.

如果-falign-loops或-falign-jumps适用且大于此值,则使用它们的值.

如果未指定n或为零,则使用机器相关的默认值,该默认值很可能为"1",表示没有对齐.

在-O2,-O3级别启用.

考虑这个标志会使它失去更多的意义......有引发代码缓存未命中的后果,甚至启用意味着何时参数采用数值(1 ..)?

c++ gcc memory-alignment compiler-optimization

7
推荐指数
1
解决办法
185
查看次数

可以使用char []作为参数,返回等执行任何性能问题吗?

首先要使C++代码更具可读性; 我编程编译器,我给了它:

var swap = ( int x, y ) => { //Assign method that returns two ints, and gets two ints as parameter to variable named swap.
    var NewX = y
    var NewY = x
}
var increment = ( int x ) => {
    var Result = x + 1
}
Run Code Online (Sandbox Code Playgroud)

注意:函数返回其首字母大写的任何变量.swap可以像使用一样使用... = swap( x, y ).NewX,但increment可以直接使用... = increment( x ).

经过一些优化后,它生成:(制造swapincrement实际的功能,而不是变量和优化swap的堆栈)

template<int BytesCount> …
Run Code Online (Sandbox Code Playgroud)

c++ gcc

5
推荐指数
1
解决办法
138
查看次数

如何覆盖基类\结构,如int,string?

减少downvotes :(起初可跳过)

我知道这个问题听起来毫无意义和/或奇怪.我正在创建JIT,它使用C#代码用csc.exe编译它,提取IL并将其平行化为CUDA,我想覆盖C#中的一些东西.

如何覆盖基础的东西,如int\ string?我试过了:

class String { /* In namespace System of course */
    BasicString wrap_to;
    public String( ) {
        wrap_to = new BasicString( 32 ); // capacity
    }
    public String( int Count ) {
        wrap_to = new BasicString( Count );
    }
    public char this[ int index ] {
        get { return wrap_to[ index ]; }
        set {
            if ( wrap_to.Handlers != 1 )
                wrap_to = new BasicString( wrap_to );
            wrap_to[ index ] = value;
        } …
Run Code Online (Sandbox Code Playgroud)

c# reflection il decompiling

5
推荐指数
1
解决办法
1061
查看次数

我可以为C#创建自己的JIT\Interpreter\Compiler并在Visual Studio中使用它吗?

我目前正在编写一个从C#生成类似JIT的EXE(重写自身)的编译器,无论如何都要使Visual Studio和它的调试器识别我想要构建它的方式(使用我的编译器)并调试输出?

我的编译器输出是EXE,但它不包含MSIL,它包含我的中间语言,其余内容是用C++编写的JIT.(C++自己读取\ EXE并执行)

我很清楚让它兼容并不神奇; 无论有什么可能,我都会在这里得到一个直接的答案并提示开始; 例如,编写带有这些函数和参数的C++ DLL,并给出Visual Studio调试器参数的DLL路径,或者只是指向我在MSDN上的引用.(我从谷歌那里获得了零结果)

c# c++ compiler-construction visual-studio visual-studio-debugging

5
推荐指数
1
解决办法
365
查看次数

我如何限制堆的大小,所以当我分配很多时,它不会让机器卡住?

我必须调试程序,有时快速分配内存(不是设计.)当它发生时我的整个计算机只是停止响应因为物理内存100%(我有4GB内存),然后我必须每次都按下重启按钮没有知道为什么会这样的方式.

有没有办法限制newmalloc堆的大小?通过限制我的意思是它将像C#一样抛出异常OutOfMemoryException.注意:我不能只选择所有news和mallocs并用自定义分配器替换它,这是很多工作.

我尝试将项目属性 - >配置属性 - >链接器 - >系统 - >堆保留\提交大小设置为256MB256000000但没有任何作用.

c++ windows memory-management heap-memory visual-studio

4
推荐指数
1
解决办法
187
查看次数

如何在最大化有效性的同时,将3态位运算符按位实现到任意大小的内存?

我可以使用2位到每个3状态位来实现它,[00-第一,10秒,11\01-第三],但是当第二位被使能时,第一位是无用的.从理论上讲,这种方法的实现将超过这种方法(我提到的2位),大小为37%.(这是1-log3(2))

我已经尝试过的代码:

#define uint unsigned int

uint set( uint x, uint place, uint value ) {
    double result = ( double )x;
    result /= pow( 3, place );
    result += value - ( ( uint )result ) % 3;
    return result * pow( 3, place );
}
uint get( uint x, uint place ) {
    return ( ( uint )( ( ( double )x ) / pow( 3, place ) ) ) % 3;
}

int main( ) …
Run Code Online (Sandbox Code Playgroud)

c++ bit-manipulation

3
推荐指数
1
解决办法
268
查看次数

中途使变量无法使用/无法访问

假设我有这段代码:

for (int i = 0; i < x.size(); i++) {
    auto &in = input[i];
    auto &func = functions[i];
    auto &out = output[i];
    // pseudo-code from here:
    unaccessiable(i);
    i = func(in); // error, i is not declared
    out = func(i); // error, i is not declared
    // useful when you mistake in/out for i
}
Run Code Online (Sandbox Code Playgroud)

我需要实现在代码中的某一行之后无法访问或使用变量的效果.(在此代码中,之后unaccessiable(i))具体我想要禁用for循环的迭代器.

注意:这仅用于代码正确性,除此之外什么都没有.所以lambdas(非编译时解决方案)只是性能阻碍.

c++

2
推荐指数
1
解决办法
150
查看次数

我怎样才能保证在释放内存时,操作系统会回收内存以供其使用?

我注意到这个程序:

#include <stdio.h>

int main() {
  const size_t alloc_size = 1*1024*1024;
  for (size_t i = 0; i < 3; i++) {
    printf("1\n");
    usleep(1000*1000);
    void *p[3];
    for (size_t j = 3; j--; )
      memset(p[j] = malloc(alloc_size),0,alloc_size); // memset for de-virtualize the memory
    usleep(1000*1000);
    printf("2\n");
    free(p[i]);
    p[i] = NULL;
    usleep(1000*1000*4);
    printf("3\n");
    for (size_t j = 3; j--; )
      free(p[j]);
  }
}
Run Code Online (Sandbox Code Playgroud)

它分配3个存储器,3次,每次释放不同的存储器,根据存储器释放存储器watch free -m,这意味着free无论存储器在程序地址空间内的位置如何,OS都会为每个存储器回收存储器.我可以以某种方式得到这种效果的保证吗?或者是否已经有类似的东西(比如>64KB分配规则)?

c linux memory memory-management

2
推荐指数
1
解决办法
133
查看次数