如果你的编译器实际上优化了每个函数只有两个寄存器变量的访问时间,那么下面程序中哪两个变量最好用于寄存器变量?
void main(void)
{
int i,j,k,m;
do
{
printf("enter value");
scanf(“%d”,&i);
m=0;
for(k=0;k<100;k++)
m=k+m;
}
while(i>0);
}
Run Code Online (Sandbox Code Playgroud)
如果有任何错误,请忽略...
例如:
#include <stdio.h>
#include <string>
int main() {
std::string* stuff(NULL);
printf("allocating memory..."); //line 2
stuff = new std::string[500000000]; //line 3
delete [] stuff; //line 4
return 0;
}
Run Code Online (Sandbox Code Playgroud)
执行时在第2行之前运行第3行(可能还有第4行).现在我知道这可能是一些很好的优化功能,但有时需要正确的顺序.
我将以一种非常简化的形式陈述我的问题,即:
如果我输入C
void main(){
int a=3+2;
double b=7/2;
}
Run Code Online (Sandbox Code Playgroud)
将a和b分配给它们的值为5和3.5是在我编译代码时还是在运行代码时?
换句话说,当我按下编译时会发生什么?以及它与我按下运行时的情况有何不同,在分配值和进行计算方面,与编写代码的方式有何不同:
void main(){
int a=5;
double b=3.5;
}
Run Code Online (Sandbox Code Playgroud)
我问这个是因为我听说过编译器优化,但它并不是我的领域.
任何评论,评论将受到高度赞赏.谢谢.
我有这么简单的代码,但我不知道为什么我不能让它工作.
tagName="Hello";
String value="Hello";
if (tagName!=null && tagName.equals(value))
{
int io=0;
}
Run Code Online (Sandbox Code Playgroud)
tagName不是null并且明显等于value但代码永远不会出现这种情况int io=0;
我想第一次编写Compiler,我的参考文献是"编译器原理,技术和工具".对于词法设计,我写了我的语言标记的FA,现在我想从状态转换表编写C#代码,但它是一个40 X 30矩阵,在这个矩阵中只有50个条目!我想压缩这个稀疏矩阵!书中有一种方法说:
有一个更微妙的数据结构允许我们将数组访问的速度与默认的列表压缩相结合.我们可以将这个结构看作四个数组,如图3.66.5所示.基数组用于确定状态s的条目的基本位置,它们位于下一个和检查数组中.如果检查数组告诉我们base [s]给出的那个是无效的,则默认数组用于确定替代基本位置.为了计算nextState(s,a),输入a上状态s的转换,我们检查下一个并检查位置l = base [s] + a中的条目,其中字符a被视为整数,大概在0的范围内如果检查[l] = s,则此条目有效,输入a上状态s的下一个状态为next [l].如果检查[l]!= s,那么我们确定另一个状态t = default [s]并重复该过程,好像t是当前状态.更正式地说,函数nextstate定义如下:
Run Code Online (Sandbox Code Playgroud)int nextState(s, a) { if ( check[base[s] + a] = s ) return next[base[s] + a]; else return nextState(default[s], a); }
我不明白这四个数组是由什么组成的?任何人都能为我解释一下吗?你有另一个简单的算法来优化我的代码进行稀疏压缩吗?我知道CSR压缩但是我不知道如何使用它们在我的C#代码中编写nextState(s,a)!你有什么想法吗?
我的代码中有以下行:
1 || printf("A");
Run Code Online (Sandbox Code Playgroud)
我很惊讶地看到A没有打印; 我猜这是由于编译器优化:1被评估为真,并且,因为整个OR表达式必须是真的,printf("A")甚至没有评估...有人可以证实这一点吗?使用不同的编译器,程序会表现得像这样吗?
我知道我应该使用volatile关键字告诉编译器不要优化内存read\write到变量.我也知道在大多数情况下它应该只用于与非C++内存通信.
但是,我想知道volatile在持有指向某个本地(堆栈)变量的指针时是否必须使用.
例如:
//global or member variable
/* volatile? */bool* p_stop;
void worker()
{
/* volatile? */ bool stop = false;
p_stop = &stop;
while(!stop)
{
//Do some work
//No usage of "stop" or p_stop" here
}
}
void stop_worker()
{
*p_stop = true;
}
Run Code Online (Sandbox Code Playgroud)
它看起来像一个编译器,有一些优化级别可能会看到这stop是一个局部变量,它永远不会改变,可以替换while(!stop)为a while(true),从而改变*p_stop而什么都不做.
那么,在这种情况下是否需要将指针标记为易失性?
PS:请不要告诉我为什么不使用它,使用这个hack的真正代码是为了(复杂到解释)的原因.
编辑:
我没有提到这两个函数在不同的线程上运行.它worker()是第一个线程的函数,应该使用p_stop指针从另一个线程停止.
我不知道有什么更好的方法来解决这种黑客背后的真正原因.我只是想知道这是否是C++中定义的\未定义的行为(11),如果这是依赖于编译器\ platform\etc的话.到目前为止,我看到@Puppy说每个人都错了,这是错误的,但没有引用表示这个的特定标准.
我知道你们中的一些人被"不要讲我"这一部分所冒犯,但请坚持真正的问题 - 我应该使用volatile与否?或者是这个UB?如果你能提供一个完整的答案,请帮助我(和其他人)学习新的东西.
在C++中考虑以下代码:
#include <cstdlib>
std::size_t count(std::size_t n)
{
std::size_t i = 0;
while (i < n) {
asm volatile("": : :"memory");
++i;
}
return i;
}
int main(int argc, char* argv[])
{
return count(argc > 1 ? std::atoll(argv[1]) : 1);
}
Run Code Online (Sandbox Code Playgroud)
它只是一个递增其值的循环,并在最后返回它.所述asm volatile防止环路它被优化.我们编译下g++ 8.1和clang++ 5.0与争论-Wall -Wextra -std=c++11 -g -O3.
现在,如果我们看一下编译器资源管理器正在生成什么,我们有g++:
count(unsigned long):
mov rax, rdi
test rdi, rdi
je .L2
xor edx, edx
.L3:
add rdx, 1
cmp rax, …Run Code Online (Sandbox Code Playgroud) 简单编写C文件如下:
int main()
{
int a = 999;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在使用gcc编译和链接之后,它将生成一个可执行文件(例如.exe,.out)
但是当我用某个编辑器打开(NOT RUNNING)可执行文件时,我找不到变量'a'的值,以十六进制表示的数字999是0x3E7.
我的问题是:
PS:我对.data .bss .text .etc和汇编语言等内存部分有一点了解.我甚至无法使用ollydbg找到它.
这是我的代码:
#include<iostream>
const int & Min(const int& a, const int& b);
int main() {
using namespace std;
auto&& val = Min(1,2);
cout << val << endl;
return 0;
}
const int & Min(const int& a, const int& b) {
return a < b ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用O0选项编译它g++ -O0 main.cpp -o main,结果是1.如果我使用O2选项编译g++ -O2 main.cpp -o main,则会得到0的结果.
为什么会给出不同的结果?