让我们有一个名为myClass的小类。我很感兴趣的是,当方法内联或不内联时,如何看待. ash的差异。我制作了两个程序,在cpp文件中带有和不带有内联关键字,但. ash的输出是相同的。我知道内联只是编译器的提示,很有可能我是优化的受害者,但有可能在一个小的cpp示例中看到内联和非内联方法的差异吗?
h:
#ifndef CLASS_H
#define CLASS_H
class myClass{
private:
int a;
public:
int getA() const;
};
#endif
cpp:
#include <class.h>
inline int myCLass::getA() const{
return a;
};
主要:
#include "class.h"
int main(){
myClass a;
a.getA();
return 0;
}
附注:
gcc -S -O0 main.cpp
两种情况下的ASM输出:
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 14
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
leaq -8(%rbp), %rdi
movl $0, -4(%rbp)
callq __ZNK7myClass4getAEv
xorl %ecx, %ecx
movl %eax, -12(%rbp) ## 4-byte Spill
movl %ecx, %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
## -- End function
.subsections_via_symbols
< code>inline关键字与告诉编译器内联调用函数没有什么关系。< code>inline的作用是允许在头中内联定义函数。
在函数定义中使用< code>inline关键字允许在多个翻译单元中定义函数,只要所有定义都相同,就不会违反一个定义规则。
在头文件中定义内联函数可以通过允许完整定义在多个翻译单元中可见来帮助编译器内联函数调用,但这就是内联
关键字与内联调用的全部关系。
为了可靠地内联函数,函数的完整定义必须在出现调用的翻译单元中可用。
因为myClass::getA()
的定义对main不可见。c
,函数不能内联。它可能在myClass中出现的任何调用中内联。cpp
,但您没有这些。
要允许此函数内联,需要在头文件中将其声明为inline
,并包含其定义,例如。
class myClass {
…
inline int getA() const { return a; }
…
}
你没有给编译器一个内联< code>myClass::getA()的机会(另一个回答里有解释)。要比较行内方法和行外方法,请比较下面代码中的< code>getA()和< code>getAlt()的用法
// file.h
class myClass
{
int a=1;
public:
int getA() const { return a; } // implicitly inline
int getAlt() const;
};
// file.cc
#include "file.h"
int myClass::getAlt() const
{ return a; }
// main.cc
#include "file.h"
int main()
{
myClass x;
return x.getA() - x.getAlt();
}
除了过程间优化之外,您可以使用完全优化(ipo;因为这可能允许编译器甚至内联myClass::getAlt()
)。
5. C内联汇编 用C写程序比直接用汇编写程序更简洁,可读性更好,但效率可能不如汇编程序,因为C程序毕竟要经由编译器生成汇编代码,尽管现代编译器的优化已经做得很好了,但还是不如手写的汇编代码。另外,有些平台相关的指令必须手写,在C语言中没有等价的语法,因为C语言的语法和概念是对各种平台的抽象,而各种平台特有的一些东西就不会在C语言中出现了,例如x86是端口I/O,而C语言就没有这个概念,所以in/
为了极端底层操作和性能要求,你可能希望直接控制 CPU。Rust 通过asm!宏来支持使用内联汇编。 asm!(assembly template : output operands : input operands : clobbers : options ); 任何asm的使用需要功能通道(需要在包装箱上加上#![feature(asm)]来允许使用)并且当然也
问题内容: 溢出, 如何仅使用内联汇编实现putchar(char)过程?我想在x86-64汇编中做到这一点。我这样做的原因是实现我自己的标准库(或至少一部分)。这是我到目前为止的内容: 我正在编译: 感谢您的帮助! 问题答案: 使用GNU C内联asm时,请 使用约束来告诉编译器您想要的东西 ,而不是使用asm模板中的指令“手动”进行。 对于和,我们只需要为模板,用约束来设置所有寄存器输入(与所
为了增强对语言的细粒度的控制,特别是在写通用库时,可以在一个语言中交错使用Solidity的语句来接近其中一个虚拟机。但由于EVM是基于栈执行的,所以有时很难定位到正确的栈槽位,从而提供正确的的参数或操作码。Solidit的内联汇编尝试解决这个问题,但也引入了其它的问题,当你通过下述特性进行手动的汇编时: 函数式的操作码:mul(1, add(2, 3))代替push1 3 push1 2 add
GCC扩展内联汇编 使用GCC扩展内联汇编的例子如下: #define read_cr0() ({ \ unsigned int __dummy; \ __asm__( \ "movl %%cr0,%0\n\t" \ :"=r" (__dummy)); \ __dummy; \ }) 它代表什么含义呢?这需要从其基本格式讲起。GCC扩展内联汇编的基本格式是: asm [volat
GCC基本内联汇编 GCC 提供了两内内联汇编语句(inline asm statements):基本内联汇编语句(basic inline asm statement)和扩展内联汇编语句(extended inline asm statement)。GCC基本内联汇编很简单,一般是按照下面的格式: asm("statements"); 例如: asm("nop"); asm("