jjzjj

c++ - C++平台依赖吗?

coder 2023-05-03 原文

我们可以说C++依赖于平台吗?

我知道C++使用编译器,并且这些编译器对于不同的平台是不同的。例如,当我们使用编译器编译C++代码时:在Windows上,创建了 .EXE 格式文件。

为什么 .EXE 文件与OS/平台相关?

.EXE文件中的格式是什么?

为什么我们不能在其他平台上运行它?

最佳答案

这实际上是一个相对广泛的话题。为简单起见,它归结为两件事:操作系统和CPU体系结构。

首先,*。exe通常仅是Windows,因为它是Windows操作系统知道如何执行的二进制代码。此外,操作系统知道如何将其转换为适合该体系结构的代码(这就是Windows“完全兼容”的原因)。请注意,还有很多事情要做,但这是对正在发生的事情的(非常)高层次的抽象。

现在,编译器将使用C++代码并为该体系结构生成相应的汇编代码(即x86,MIPS等)。通常,编译器还具有一个汇编程序(或它可以依赖的汇编程序)。汇编器链接代码并生成可由硬件执行的二进制代码。有关此主题的更多信息,请查找有关热电联产的更多信息。

附加说明

考虑不依赖平台的Java。 Java编译器生成Java字节码,该字节码在Java虚拟机(JVM)上运行。重要的是要注意,任何时候只要您想运行Java应用程序,都必须运行Java虚拟机。由于预编译的JVM知道如何在您的操作系统和CPU体系结构上运行,因此它可以运行其Java字节码并有效地为您的特定系统运行相应的操作。

在一个已编译的二进制文件(即C++代码中的一个)中,您具有系统字节码。因此,Java为您模拟的指令类型直接硬编码为.exe或您使用的任何二进制格式。考虑以下示例:

请注意,此Java代码最终必须在JVM中运行,并且不能独立运行。

Java Code:
System.out.println("hello") (To be compiled)

Compiled Java bytecode:
Print "hello" (To be run in JVM)

JVM:
(... some translation, maybe to architecture code - I forget exactly ...)
system_print_code "hello" (JVM translation to CPU specific)

与C++(可在独立模式下运行):
C++ Code:
cout<< "hello";

Architecture Code:
some_assembly_routine "hello"

Binary output:
system_print_code "hello"

一个真实的例子

如果您对实际示例中的实际情况感到好奇,我在下面提供了一个示例。

C++源
我把它放在了一个名为hello.cpp的文件中
#include <iostream>

int main() {
  using namespace std;
  cout << "Hello world!" << endl;
  return 0;
}

程序集(从C++源生成)
通过g++ -S hello.cpp生成
    .file   "test.c"
    .section    .rodata
    .type   _ZStL19piecewise_construct, @object
    .size   _ZStL19piecewise_construct, 1
_ZStL19piecewise_construct:
    .zero   1
    .local  _ZStL8__ioinit
    .comm   _ZStL8__ioinit,1,1
.LC0:
    .string "Hello world!"
    .text
    .globl  main
    .type   main, @function
main:
.LFB1493:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    leaq    .LC0(%rip), %rsi
    leaq    _ZSt4cout(%rip), %rdi
    call    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
    movq    %rax, %rdx
    movq    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rax
    movq    %rax, %rsi
    movq    %rdx, %rdi
    call    _ZNSolsEPFRSoS_E@PLT
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1493:
    .size   main, .-main
    .type   _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB1982:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movl    %esi, -8(%rbp)
    cmpl    $1, -4(%rbp)
    jne .L5
    cmpl    $65535, -8(%rbp)
    jne .L5
    leaq    _ZStL8__ioinit(%rip), %rdi
    call    _ZNSt8ios_base4InitC1Ev@PLT
    leaq    __dso_handle(%rip), %rdx
    leaq    _ZStL8__ioinit(%rip), %rsi
    movq    _ZNSt8ios_base4InitD1Ev@GOTPCREL(%rip), %rax
    movq    %rax, %rdi
    call    __cxa_atexit@PLT
.L5:
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1982:
    .size   _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
    .type   _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB1983:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $65535, %esi
    movl    $1, %edi
    call    _Z41__static_initialization_and_destruction_0ii
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1983:
    .size   _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
    .section    .init_array,"aw"
    .align 8
    .quad   _GLOBAL__sub_I_main
    .hidden __dso_handle
    .ident  "GCC: (GNU) 7.2.1 20171128"
    .section    .note.GNU-stack,"",@progbits

二进制输出(从程序集生成)
这是通过g++ -c以十六进制形式生成的二进制输出的未链接形式(即尚未完全填充符号位置)。我使用xxd生成了十六进制表示形式。
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0100 3e00 0100 0000 0000 0000 0000 0000  ..>.............
00000020: 0000 0000 0000 0000 0807 0000 0000 0000  ................
00000030: 0000 0000 4000 0000 0000 4000 0f00 0e00  ....@.....@.....
00000040: 5548 89e5 488d 3500 0000 0048 8d3d 0000  UH..H.5....H.=..
00000050: 0000 e800 0000 0048 89c2 488b 0500 0000  .......H..H.....
00000060: 0048 89c6 4889 d7e8 0000 0000 b800 0000  .H..H...........
00000070: 005d c355 4889 e548 83ec 1089 7dfc 8975  .].UH..H....}..u
00000080: f883 7dfc 0175 3281 7df8 ffff 0000 7529  ..}..u2.}.....u)
00000090: 488d 3d00 0000 00e8 0000 0000 488d 1500  H.=.........H...
000000a0: 0000 0048 8d35 0000 0000 488b 0500 0000  ...H.5....H.....
000000b0: 0048 89c7 e800 0000 0090 c9c3 5548 89e5  .H..........UH..
000000c0: beff ff00 00bf 0100 0000 e8a4 ffff ff5d  ...............]
000000d0: c300 4865 6c6c 6f20 776f 726c 6421 0000  ..Hello world!..
000000e0: 0000 0000 0000 0000 0047 4343 3a20 2847  .........GCC: (G
000000f0: 4e55 2920 372e 322e 3120 3230 3137 3131  NU) 7.2.1 201711
00000100: 3238 0000 0000 0000 1400 0000 0000 0000  28..............
00000110: 017a 5200 0178 1001 1b0c 0708 9001 0000  .zR..x..........
00000120: 1c00 0000 1c00 0000 0000 0000 3300 0000  ............3...
00000130: 0041 0e10 8602 430d 066e 0c07 0800 0000  .A....C..n......
00000140: 1c00 0000 3c00 0000 0000 0000 4900 0000  ....<.......I...
00000150: 0041 0e10 8602 430d 0602 440c 0708 0000  .A....C...D.....
00000160: 1c00 0000 5c00 0000 0000 0000 1500 0000  ....\...........
00000170: 0041 0e10 8602 430d 0650 0c07 0800 0000  .A....C..P......
00000180: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000190: 0000 0000 0000 0000 0100 0000 0400 f1ff  ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001b0: 0000 0000 0300 0100 0000 0000 0000 0000  ................
000001c0: 0000 0000 0000 0000 0000 0000 0300 0300  ................
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0300 0400 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0300 0500  ................
00000200: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000210: 0800 0000 0100 0500 0000 0000 0000 0000  ................
00000220: 0100 0000 0000 0000 2300 0000 0100 0400  ........#.......
00000230: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000240: 3200 0000 0200 0100 3300 0000 0000 0000  2.......3.......
00000250: 4900 0000 0000 0000 6200 0000 0200 0100  I.......b.......
00000260: 7c00 0000 0000 0000 1500 0000 0000 0000  |...............
00000270: 0000 0000 0300 0600 0000 0000 0000 0000  ................
00000280: 0000 0000 0000 0000 0000 0000 0300 0900  ................
00000290: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000002a0: 0000 0000 0300 0a00 0000 0000 0000 0000  ................
000002b0: 0000 0000 0000 0000 0000 0000 0300 0800  ................
000002c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000002d0: 7100 0000 1200 0100 0000 0000 0000 0000  q...............
000002e0: 3300 0000 0000 0000 7600 0000 1000 0000  3.......v.......
000002f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000300: 8000 0000 1000 0000 0000 0000 0000 0000  ................
00000310: 0000 0000 0000 0000 9600 0000 1000 0000  ................
00000320: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000330: ce00 0000 1000 0000 0000 0000 0000 0000  ................
00000340: 0000 0000 0000 0000 0901 0000 1000 0000  ................
00000350: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000360: 1a01 0000 1000 0000 0000 0000 0000 0000  ................
00000370: 0000 0000 0000 0000 3201 0000 1002 0000  ........2.......
00000380: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000390: 3f01 0000 1000 0000 0000 0000 0000 0000  ?...............
000003a0: 0000 0000 0000 0000 5701 0000 1000 0000  ........W.......
000003b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003c0: 0074 6573 742e 6300 5f5a 5374 4c31 3970  .test.c._ZStL19p
000003d0: 6965 6365 7769 7365 5f63 6f6e 7374 7275  iecewise_constru
000003e0: 6374 005f 5a53 744c 385f 5f69 6f69 6e69  ct._ZStL8__ioini
000003f0: 7400 5f5a 3431 5f5f 7374 6174 6963 5f69  t._Z41__static_i
00000400: 6e69 7469 616c 697a 6174 696f 6e5f 616e  nitialization_an
00000410: 645f 6465 7374 7275 6374 696f 6e5f 3069  d_destruction_0i
00000420: 6900 5f47 4c4f 4241 4c5f 5f73 7562 5f49  i._GLOBAL__sub_I
00000430: 5f6d 6169 6e00 5f5a 5374 3463 6f75 7400  _main._ZSt4cout.
00000440: 5f47 4c4f 4241 4c5f 4f46 4653 4554 5f54  _GLOBAL_OFFSET_T
00000450: 4142 4c45 5f00 5f5a 5374 6c73 4953 7431  ABLE_._ZStlsISt1
00000460: 3163 6861 725f 7472 6169 7473 4963 4545  1char_traitsIcEE
00000470: 5253 7431 3362 6173 6963 5f6f 7374 7265  RSt13basic_ostre
00000480: 616d 4963 545f 4553 355f 504b 6300 5f5a  amIcT_ES5_PKc._Z
00000490: 5374 3465 6e64 6c49 6353 7431 3163 6861  St4endlIcSt11cha
000004a0: 725f 7472 6169 7473 4963 4545 5253 7431  r_traitsIcEERSt1
000004b0: 3362 6173 6963 5f6f 7374 7265 616d 4954  3basic_ostreamIT
000004c0: 5f54 305f 4553 365f 005f 5a4e 536f 6c73  _T0_ES6_._ZNSols
000004d0: 4550 4652 536f 535f 4500 5f5a 4e53 7438  EPFRSoS_E._ZNSt8
000004e0: 696f 735f 6261 7365 3449 6e69 7443 3145  ios_base4InitC1E
000004f0: 7600 5f5f 6473 6f5f 6861 6e64 6c65 005f  v.__dso_handle._
00000500: 5a4e 5374 3869 6f73 5f62 6173 6534 496e  ZNSt8ios_base4In
00000510: 6974 4431 4576 005f 5f63 7861 5f61 7465  itD1Ev.__cxa_ate
00000520: 7869 7400 0000 0000 0700 0000 0000 0000  xit.............
00000530: 0200 0000 0500 0000 fdff ffff ffff ffff  ................
00000540: 0e00 0000 0000 0000 0200 0000 0f00 0000  ................
00000550: fcff ffff ffff ffff 1300 0000 0000 0000  ................
00000560: 0400 0000 1100 0000 fcff ffff ffff ffff  ................
00000570: 1d00 0000 0000 0000 2a00 0000 1200 0000  ........*.......
00000580: fcff ffff ffff ffff 2800 0000 0000 0000  ........(.......
00000590: 0400 0000 1300 0000 fcff ffff ffff ffff  ................
000005a0: 5300 0000 0000 0000 0200 0000 0400 0000  S...............
000005b0: fcff ffff ffff ffff 5800 0000 0000 0000  ........X.......
000005c0: 0400 0000 1400 0000 fcff ffff ffff ffff  ................
000005d0: 5f00 0000 0000 0000 0200 0000 1500 0000  _...............
000005e0: fcff ffff ffff ffff 6600 0000 0000 0000  ........f.......
000005f0: 0200 0000 0400 0000 fcff ffff ffff ffff  ................
00000600: 6d00 0000 0000 0000 2a00 0000 1600 0000  m.......*.......
00000610: fcff ffff ffff ffff 7500 0000 0000 0000  ........u.......
00000620: 0400 0000 1700 0000 fcff ffff ffff ffff  ................
00000630: 0000 0000 0000 0000 0100 0000 0200 0000  ................
00000640: 7c00 0000 0000 0000 2000 0000 0000 0000  |....... .......
00000650: 0200 0000 0200 0000 0000 0000 0000 0000  ................
00000660: 4000 0000 0000 0000 0200 0000 0200 0000  @...............
00000670: 3300 0000 0000 0000 6000 0000 0000 0000  3.......`.......
00000680: 0200 0000 0200 0000 7c00 0000 0000 0000  ........|.......
00000690: 002e 7379 6d74 6162 002e 7374 7274 6162  ..symtab..strtab
000006a0: 002e 7368 7374 7274 6162 002e 7265 6c61  ..shstrtab..rela
000006b0: 2e74 6578 7400 2e64 6174 6100 2e62 7373  .text..data..bss
000006c0: 002e 726f 6461 7461 002e 7265 6c61 2e69  ..rodata..rela.i
000006d0: 6e69 745f 6172 7261 7900 2e63 6f6d 6d65  nit_array..comme
000006e0: 6e74 002e 6e6f 7465 2e47 4e55 2d73 7461  nt..note.GNU-sta
000006f0: 636b 002e 7265 6c61 2e65 685f 6672 616d  ck..rela.eh_fram
00000700: 6500 0000 0000 0000 0000 0000 0000 0000  e...............
00000710: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000720: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000730: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000740: 0000 0000 0000 0000 2000 0000 0100 0000  ........ .......
00000750: 0600 0000 0000 0000 0000 0000 0000 0000  ................
00000760: 4000 0000 0000 0000 9100 0000 0000 0000  @...............
00000770: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000780: 0000 0000 0000 0000 1b00 0000 0400 0000  ................
00000790: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
000007a0: 2805 0000 0000 0000 0801 0000 0000 0000  (...............
000007b0: 0c00 0000 0100 0000 0800 0000 0000 0000  ................
000007c0: 1800 0000 0000 0000 2600 0000 0100 0000  ........&.......
000007d0: 0300 0000 0000 0000 0000 0000 0000 0000  ................
000007e0: d100 0000 0000 0000 0000 0000 0000 0000  ................
000007f0: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000800: 0000 0000 0000 0000 2c00 0000 0800 0000  ........,.......
00000810: 0300 0000 0000 0000 0000 0000 0000 0000  ................
00000820: d100 0000 0000 0000 0100 0000 0000 0000  ................
00000830: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000840: 0000 0000 0000 0000 3100 0000 0100 0000  ........1.......
00000850: 0200 0000 0000 0000 0000 0000 0000 0000  ................
00000860: d100 0000 0000 0000 0e00 0000 0000 0000  ................
00000870: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000880: 0000 0000 0000 0000 3e00 0000 0e00 0000  ........>.......
00000890: 0300 0000 0000 0000 0000 0000 0000 0000  ................
000008a0: e000 0000 0000 0000 0800 0000 0000 0000  ................
000008b0: 0000 0000 0000 0000 0800 0000 0000 0000  ................
000008c0: 0800 0000 0000 0000 3900 0000 0400 0000  ........9.......
000008d0: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
000008e0: 3006 0000 0000 0000 1800 0000 0000 0000  0...............
000008f0: 0c00 0000 0600 0000 0800 0000 0000 0000  ................
00000900: 1800 0000 0000 0000 4a00 0000 0100 0000  ........J.......
00000910: 3000 0000 0000 0000 0000 0000 0000 0000  0...............
00000920: e800 0000 0000 0000 1b00 0000 0000 0000  ................
00000930: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000940: 0100 0000 0000 0000 5300 0000 0100 0000  ........S.......
00000950: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000960: 0301 0000 0000 0000 0000 0000 0000 0000  ................
00000970: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000980: 0000 0000 0000 0000 6800 0000 0100 0000  ........h.......
00000990: 0200 0000 0000 0000 0000 0000 0000 0000  ................
000009a0: 0801 0000 0000 0000 7800 0000 0000 0000  ........x.......
000009b0: 0000 0000 0000 0000 0800 0000 0000 0000  ................
000009c0: 0000 0000 0000 0000 6300 0000 0400 0000  ........c.......
000009d0: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
000009e0: 4806 0000 0000 0000 4800 0000 0000 0000  H.......H.......
000009f0: 0c00 0000 0a00 0000 0800 0000 0000 0000  ................
00000a00: 1800 0000 0000 0000 0100 0000 0200 0000  ................
00000a10: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000a20: 8001 0000 0000 0000 4002 0000 0000 0000  ........@.......
00000a30: 0d00 0000 0e00 0000 0800 0000 0000 0000  ................
00000a40: 1800 0000 0000 0000 0900 0000 0300 0000  ................
00000a50: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000a60: c003 0000 0000 0000 6401 0000 0000 0000  ........d.......
00000a70: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000a80: 0000 0000 0000 0000 1100 0000 0300 0000  ................
00000a90: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000aa0: 9006 0000 0000 0000 7200 0000 0000 0000  ........r.......
00000ab0: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000ac0: 0000 0000 0000 0000                      ........

这些指令对应于x86_64机器。如果您有兴趣遵循并匹配操作码,则可以使用look at this referencedownload the Intel manual以获得完整性。同样,它是一个ELF文件,因此您可以观察到我们看到了我们期望的内容(即0x7f的起始魔术数等)。

无论如何,一旦与系统链接(即运行g++ test.cppg++ test.sg++ test.o),此可执行文件就可以直接在您的操作系统之上运行。在此操作系统之间没有其他翻译层。即使这样,OS仍会做OS事情,例如抽象硬件接口(interface),管理系统资源等。

将此问题与最初的问题联系起来,在Windows机器上(对于相同的C++代码)输出二进制文件看起来将非常不同。至少,在Windows计算机上,您希望看到Portable Executable (PE) format中的文件,该文件显然不是ELF。

这与以下需要运行JVM的Java示例不同:

Java源文件
这放置在名为Test.java的文件中
package mytest;

public class Test {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}

Java字节码(从Java源代码生成)
这是通过运行javac -d . Test.java并通过mytest/Test.class运行输出文件(即xxd)生成的
00000000: cafe babe 0000 0034 001d 0a00 0600 0f09  .......4........
00000010: 0010 0011 0800 120a 0013 0014 0700 1507  ................
00000020: 0016 0100 063c 696e 6974 3e01 0003 2829  .....<init>...()
00000030: 5601 0004 436f 6465 0100 0f4c 696e 654e  V...Code...LineN
00000040: 756d 6265 7254 6162 6c65 0100 046d 6169  umberTable...mai
00000050: 6e01 0016 285b 4c6a 6176 612f 6c61 6e67  n...([Ljava/lang
00000060: 2f53 7472 696e 673b 2956 0100 0a53 6f75  /String;)V...Sou
00000070: 7263 6546 696c 6501 0009 5465 7374 2e6a  rceFile...Test.j
00000080: 6176 610c 0007 0008 0700 170c 0018 0019  ava.............
00000090: 0100 0c48 656c 6c6f 2077 6f72 6c64 2107  ...Hello world!.
000000a0: 001a 0c00 1b00 1c01 000b 6d79 7465 7374  ..........mytest
000000b0: 2f54 6573 7401 0010 6a61 7661 2f6c 616e  /Test...java/lan
000000c0: 672f 4f62 6a65 6374 0100 106a 6176 612f  g/Object...java/
000000d0: 6c61 6e67 2f53 7973 7465 6d01 0003 6f75  lang/System...ou
000000e0: 7401 0015 4c6a 6176 612f 696f 2f50 7269  t...Ljava/io/Pri
000000f0: 6e74 5374 7265 616d 3b01 0013 6a61 7661  ntStream;...java
00000100: 2f69 6f2f 5072 696e 7453 7472 6561 6d01  /io/PrintStream.
00000110: 0007 7072 696e 746c 6e01 0015 284c 6a61  ..println...(Lja
00000120: 7661 2f6c 616e 672f 5374 7269 6e67 3b29  va/lang/String;)
00000130: 5600 2100 0500 0600 0000 0000 0200 0100  V.!.............
00000140: 0700 0800 0100 0900 0000 1d00 0100 0100  ................
00000150: 0000 052a b700 01b1 0000 0001 000a 0000  ...*............
00000160: 0006 0001 0000 0003 0009 000b 000c 0001  ................
00000170: 0009 0000 0025 0002 0001 0000 0009 b200  .....%..........
00000180: 0212 03b6 0004 b100 0000 0100 0a00 0000  ................
00000190: 0a00 0200 0000 0500 0800 0600 0100 0d00  ................
000001a0: 0000 0200 0e                             .....

正如人们所期望的那样,字节码输出starts with 0xCAFEBABE

但是,此处的关键区别是该代码无法直接运行。它仍然是二进制输出,但不打算由操作系统直接执行。如果您尝试在系统上没有JVM的情况下运行此程序,则会收到错误消息。但是,此代码可以在包含兼容JVM的任何操作系统上运行。兼容的JVM的集合取决于set your source and target的方式。默认情况下,它等同于您用于编译的Java版本。在这种情况下,我使用了Java 8。

这种工作方式是为每个系统专门编译JVM(类似于上面的C++示例),然后将其二进制Java字节代码转换为系统现在可以执行的内容。

最终,没有免费的午餐-正如DanielKO在评论中提到的那样,JVM仍然是一个“平台”,但是它比OS高一个级别,因此看起来可以移植一些。最终,代码必须转换为对您的特定操作系统系列和CPU体系结构有效的指令。但是,对于Java和JVM,您只需为所有系统版本编译单个应用程序(即JVM本身)。到那时,可以这么说(只要您的应用程序完全是用Java编写的,并且没有使用 native 接口(interface),等等),所有在JVM之上编写的东西都具有“免费”的系统支持。

如前所述,此信息有许多警告:)这是一个非常简单的示例,旨在说明您可能实际观察到的内容。就是说,我们没有使用自定义JVM代理或任何可能会稍微影响此答案的方法来调用本地代码。通常,这些通常属于“特殊情况”类别,除非您了解原因以及(希望如此)它们对可移植性的含义,否则您将不会经常使用这些东西。

关于c++ - C++平台依赖吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11810484/

有关c++ - C++平台依赖吗?的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. ruby - 有什么方法可以告诉 sidekiq 一项工作依赖于另一项工作 - 2

    有什么方法可以告诉sidekiq一项工作依赖于另一项工作,并且在后者完成之前无法开始? 最佳答案 仅使用Sidekiq;答案是否定的。正如DickieBoy所建议的那样,您应该能够在依赖作业完成时将其启动。像这样。#app/workers/hard_worker.rbclassHardWorkerincludeSidekiq::Workerdefperform()puts'Doinghardwork'LazyWorker.perform_async()endend#app/workers/lazy_worker.rbclassLaz

  7. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  8. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  9. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  10. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

随机推荐