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上),但它不会抛出,而有趣的是它输出:
这有点预期,但它表明我们可以改变,它实际上改变了收藏.任何想法为什么会发生这种行为?
我有一个宏在我的代码中使用,在调试模式下:
#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)
条件以及依赖它的一切都已经过优化.
我的问题出现在更复杂的条件下.当编译器无法证明条件没有副作用时,它不会将其优化出来,与不使用合同相比,这是一个严重的惩罚.
有没有办法表明合同中的条件没有副作用,所以总是优化出来?
从项目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#
,没有任何相关内容,就好像它忽略了我的?.
(?)
使用以下代码编译此代码-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
字节后,这个假设被驳斥了.
这段代码:
#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) 引用自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++代码更具可读性; 我编程编译器,我给了它:
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 )
.
经过一些优化后,它生成:(制造swap
和increment
实际的功能,而不是变量和优化swap
的堆栈)
template<int BytesCount> …
Run Code Online (Sandbox Code Playgroud) 减少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#生成类似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
我必须调试程序,有时快速分配内存(不是设计.)当它发生时我的整个计算机只是停止响应因为物理内存100%(我有4GB内存),然后我必须每次都按下重启按钮没有知道为什么会这样的方式.
有没有办法限制new
或malloc
堆的大小?通过限制我的意思是它将像C#一样抛出异常OutOfMemoryException
.注意:我不能只选择所有new
s和malloc
s并用自定义分配器替换它,这是很多工作.
我尝试将项目属性 - >配置属性 - >链接器 - >系统 - >堆保留\提交大小设置为256MB
或256000000
但没有任何作用.
我可以使用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) 假设我有这段代码:
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(非编译时解决方案)只是性能阻碍.
我注意到这个程序:
#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++ ×9
c# ×4
gcc ×4
windows ×2
assert ×1
c ×1
collections ×1
decompiling ×1
heap-memory ×1
il ×1
linux ×1
memory ×1
operators ×1
optimization ×1
performance ×1
reflection ×1
visual-c++ ×1