C++ 定义默认值void locals_index(int reg, int offset = 1);

看jvm源码的时候怎么也看不懂,来回看了几次了就是关于iload 6 指令的解析

def(Bytecodes::_lload               , ubcp|____|____|____, vtos, ltos, lload               ,  _           );

看重载的def函数

  const char _    = ' ';
  const int  ____ = 0;

其中的_ 是上面的定义

void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(), char filler) {
  assert(filler == ' ', "just checkin'");
  def(code, flags, in, out, (Template::generator)gen, 0);
}
//下面对应的有参函数 对应上面的无参函数

void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(int arg), int arg) { 
  // should factor out these constants
  const int ubcp = 1 << Template::uses_bcp_bit;
  const int disp = 1 << Template::does_dispatch_bit;
  const int clvm = 1 << Template::calls_vm_bit;
  const int iswd = 1 << Template::wide_bit;
  // determine which table to use
  bool is_wide = (flags & iswd) != 0;
  // make sure that wide instructions have a vtos entry point
  // (since they are executed extremely rarely, it doesn't pay out to have an
  // extra set of 5 dispatch tables for the wide instructions - for simplicity
  // they all go with one table)
  assert(in == vtos || !is_wide, "wide instructions have vtos entry point only");
  Template* t = is_wide ? template_for_wide(code) : template_for(code);
  // setup entry
  t->initialize(flags, in, out, gen, arg);
  assert(t->bytecode() == code, "just checkin'");
}

上面没有什么能明白调用了无参的gen()函数,那么就是

void TemplateTable::iload() {
  transition(vtos, itos);
  if (RewriteFrequentPairs) {
    Label rewrite, done;

    // get next byte
    __ load_unsigned_byte(rbx, at_bcp(Bytecodes::length_for(Bytecodes::_iload)));
    // if _iload, wait to rewrite to iload2.  We only want to rewrite the
    // last two iloads in a pair.  Comparing against fast_iload means that
    // the next bytecode is neither an iload or a caload, and therefore
    // an iload pair.
    __ cmpl(rbx, Bytecodes::_iload);
    __ jcc(Assembler::equal, done);

    __ cmpl(rbx, Bytecodes::_fast_iload);
    __ movl(rcx, Bytecodes::_fast_iload2);
    __ jccb(Assembler::equal, rewrite);

    // if _caload, rewrite to fast_icaload
    __ cmpl(rbx, Bytecodes::_caload);
    __ movl(rcx, Bytecodes::_fast_icaload);
    __ jccb(Assembler::equal, rewrite);

    // rewrite so iload doesn't check again.
    __ movl(rcx, Bytecodes::_fast_iload);

    // rewrite
    // rcx: fast bytecode
    __ bind(rewrite);
    patch_bytecode(Bytecodes::_iload, rcx, rbx, false);
    __ bind(done);
  } //以上忽略

  // Get the local value into tos
  locals_index(rbx);
  __ movl(rax, iaddress(rbx));
}

接下来

void TemplateTable::locals_index(Register reg, int offset) {
  __ load_unsigned_byte(reg, at_bcp(offset));
  __ negptr(reg);
}

我开始找 locals_index() 函数,只有这个两个参数的,以为有重载,结果没有,然后查资料说是有,可以省略参数,就将0作为默认参数,就不需要写这个0了

locals_index(rbx,0)

但是逻辑不符合,应该是 locals_index(rbx,1)才对

于是又发现在hpp文件中有一个定义

  static void locals_index(Register reg, int offset = 1);

莫非这个意思是设置默认值,然后省略了 1  ?

在本地做了实验

main.hpp

#ifndef UNTITLED2_MAIN_H
#define UNTITLED2_MAIN_H

#endif //UNTITLED2_MAIN_H
static void locals_index(int reg, int offset = 1);

main.cpp

#include<stdio.h>
#include "main.h"


int main(int argc, char* argv[]){


locals_index(1);
    return 0;
}


void locals_index(int reg, int offset){
    printf("c=%d
",reg+offset);
}


//控制台打印
C:UsersmetoCLionProjectsuntitled2cmake-build-debuguntitled2.exe
c=2

Process finished with exit code 0

果然是这个样子,说明了c++有默认值的用法

小c佳,你这样子不好,让我好一顿找

原文地址:https://www.cnblogs.com/zytcomeon/p/14527994.html