Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9213409
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T01:44:33+00:00 2026-06-18T01:44:33+00:00

I am in the process of comparing Fortran 90 vs C++ for a presentation.

  • 0

I am in the process of comparing Fortran 90 vs C++ for a presentation. One of my comparisons relies on the assembly generated for simple programs by g++ and gfortran.

One example reads as follows:

#include<cstdio> // quick and dirty number formatting

template<int N>
double dot(double x[], double y[]){
  return x[N-1] * y[N-1] + dot<N-1>(x, y);
}

template<>
double dot<1>(double x[], double y[]){
  return x[0] * y[0];
}
    
int main(){
  double x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  double y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  printf("x.y = %23.16E\n", dot<10>(x, y));
}

The following assembler is generated by the command g++ -S -O3 myprogram.cpp using g++ 4.7.2 on OS X 10.7.4 x86_64-apple-darwin11.4.2:

    .text
    .align 4,0x90
    .globl __Z3dotILi1EEdPdS0_
__Z3dotILi1EEdPdS0_:
LFB2:
    movsd   (%rdi), %xmm0
    mulsd   (%rsi), %xmm0
    ret
LFE2:
    .cstring
LC1:
    .ascii "x.y = %23.16E\12\0"
    .section __TEXT,__text_startup,regular,pure_instructions
    .align 4
    .globl _main
_main:
LFB3:
    leaq    LC1(%rip), %rdi
    subq    $8, %rsp
LCFI0:
    movl    $1, %eax
    movsd   LC0(%rip), %xmm0
    call    _printf
    xorl    %eax, %eax
    addq    $8, %rsp
LCFI1:
    ret
LFE3:
    .literal8
    .align 3
LC0:
    .long   0
    .long   1081610240
    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
    .set L$set$0,LECIE1-LSCIE1
    .long L$set$0
LSCIE1:
    .long   0
    .byte   0x1
    .ascii "zR\0"
    .byte   0x1
    .byte   0x78
    .byte   0x10
    .byte   0x1
    .byte   0x10
    .byte   0xc
    .byte   0x7
    .byte   0x8
    .byte   0x90
    .byte   0x1
    .align 3
LECIE1:
LSFDE1:
    .set L$set$1,LEFDE1-LASFDE1
    .long L$set$1
LASFDE1:
    .long   LASFDE1-EH_frame1
    .quad   LFB2-.
    .set L$set$2,LFE2-LFB2
    .quad L$set$2
    .byte   0
    .align 3
LEFDE1:
LSFDE3:
    .set L$set$3,LEFDE3-LASFDE3
    .long L$set$3
LASFDE3:
    .long   LASFDE3-EH_frame1
    .quad   LFB3-.
    .set L$set$4,LFE3-LFB3
    .quad L$set$4
    .byte   0
    .byte   0x4
    .set L$set$5,LCFI0-LFB3
    .long L$set$5
    .byte   0xe
    .byte   0x10
    .byte   0x4
    .set L$set$6,LCFI1-LCFI0
    .long L$set$6
    .byte   0xe
    .byte   0x8
    .align 3
LEFDE3:
    .constructor
    .destructor
    .align 1
    .subsections_via_symbols

The dot product is 385, and it seems that it was calculated at compile time, but I cannot seem to find exactly where. I suspect it is somewhere in the following assembler segment:

    movl    $1, %eax
    movsd   LC0(%rip), %xmm0
    call    _printf
    xorl    %eax, %eax
    addq    $8, %rsp
LCFI1:
    ret
LFE3:
    .literal8
    .align 3
LC0:
    .long   0
    .long   1081610240
    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support

My (very, very limited) understanding of assembly, would tell me that the dot product was calculated by the compiler and placed in a register (LC0). Then the instruction movsd LC0(%rip), %xmm0 places the value in a string, and calls printf on the resulting, formatted string.

Is this the case? Is the actual number 385 included somewhere in this output, or is it calculated elsewhwere?

Thank you!

EDIT:

In case anybody wonders how the assembly produced by gfortran looks like, I am attaching it below. Notice that even though is known at compile time, and I’m using Fortran’s intrinsic dot_product operator, the generated assembly is substantially larger (130 lines vs. 90 lines in the C++ version), and it seems that the optimizer is not able to reduce the operation.

Program (notice that I am using the intrinsic, built-in dot_product operator):

PROGRAM MAIN
  REAL(8), DIMENSION(10):: X = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
  REAL(8), DIMENSION(10):: Y = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
  PRINT "(A, E23.16)", "x.y = ", DOT_PRODUCT(X, Y)
ENDPROGRAM MAIN

Assembly (gfortran -S -O3 myprogram.cpp using gcc 4.7.2 on OS X 10.7.4 x86_64-apple-darwin11.4.2)

    .cstring
LC0:
    .ascii "dotproduct-intrinsic.f90\0"
    .const
LC1:
    .ascii "(A, E23.16)"
LC2:
    .ascii "x.y = "
    .text
    .align 4,0x90
_MAIN__:
LFB0:
    leaq    LC0(%rip), %rax
    subq    $504, %rsp
LCFI0:
    movq    %rax, 24(%rsp)
    leaq    16(%rsp), %rdi
    leaq    LC1(%rip), %rax
    movl    $5, 32(%rsp)
    movq    %rax, 88(%rsp)
    movl    $11, 96(%rsp)
    movl    $4096, 16(%rsp)
    movl    $6, 20(%rsp)
    call    __gfortran_st_write
    leaq    16(%rsp), %rdi
    movl    $6, %edx
    leaq    LC2(%rip), %rsi
    call    __gfortran_transfer_character_write
    leaq    8(%rsp), %rsi
    movl    $8, %edx
    movabsq $4645480607818711040, %rax
    leaq    16(%rsp), %rdi
    movq    %rax, 8(%rsp)
    call    __gfortran_transfer_real_write
    leaq    16(%rsp), %rdi
    call    __gfortran_st_write_done
    addq    $504, %rsp
LCFI1:
    ret
LFE0:
    .section __TEXT,__text_startup,regular,pure_instructions
    .align 4
    .globl _main
_main:
LFB1:
    subq    $8, %rsp
LCFI2:
    call    __gfortran_set_args
    leaq    _options.3.1864(%rip), %rsi
    movl    $8, %edi
    call    __gfortran_set_options
    call    _MAIN__
    xorl    %eax, %eax
    addq    $8, %rsp
LCFI3:
    ret
LFE1:
    .const
    .align 5
_options.3.1864:
    .long   68
    .long   1023
    .long   0
    .long   0
    .long   1
    .long   1
    .long   0
    .long   1
    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
    .set L$set$0,LECIE1-LSCIE1
    .long L$set$0
LSCIE1:
    .long   0
    .byte   0x1
    .ascii "zR\0"
    .byte   0x1
    .byte   0x78
    .byte   0x10
    .byte   0x1
    .byte   0x10
    .byte   0xc
    .byte   0x7
    .byte   0x8
    .byte   0x90
    .byte   0x1
    .align 3
LECIE1:
LSFDE1:
    .set L$set$1,LEFDE1-LASFDE1
    .long L$set$1
LASFDE1:
    .long   LASFDE1-EH_frame1
    .quad   LFB0-.
    .set L$set$2,LFE0-LFB0
    .quad L$set$2
    .byte   0
    .byte   0x4
    .set L$set$3,LCFI0-LFB0
    .long L$set$3
    .byte   0xe
    .byte   0x80,0x4
    .byte   0x4
    .set L$set$4,LCFI1-LCFI0
    .long L$set$4
    .byte   0xe
    .byte   0x8
    .align 3
LEFDE1:
LSFDE3:
    .set L$set$5,LEFDE3-LASFDE3
    .long L$set$5
LASFDE3:
    .long   LASFDE3-EH_frame1
    .quad   LFB1-.
    .set L$set$6,LFE1-LFB1
    .quad L$set$6
    .byte   0
    .byte   0x4
    .set L$set$7,LCFI2-LFB1
    .long L$set$7
    .byte   0xe
    .byte   0x10
    .byte   0x4
    .set L$set$8,LCFI3-LCFI2
    .long L$set$8
    .byte   0xe
    .byte   0x8
    .align 3
LEFDE3:
    .subsections_via_symbols

Edit 2

Thanks to @JerryCoffin’s answer, I am able to verify that, indeed, the bit pattern

LC0:
    .long   0
    .long   1081610240

found in the assembly output corresponds to the number 385.

I used the exact same program provided by @JerryCoffin, namely:

#include <stdio.h>


    #pragma pack(1)
    struct x {
        long x, y;
    };    
    
    int main() { 
        x v = {0, 1081610240};
    
        printf("%f\n", *(double *)&v);
        return 0;
    }

with the only caveat that I had to compile it using 32 bits target: g++ verification.cpp -m32.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T01:44:34+00:00Added an answer on June 18, 2026 at 1:44 am

    Yes — this:

    LC0:
        .long   0
        .long   1081610240
    

    Is the bit pattern for a double with the value 3851. So what’s happening is that this:

    LCFI0:
        movl    $1, %eax
        movsd   LC0(%rip), %xmm0
        call    _printf
    

    …is loading that value into an XMM register, then calling printf to print it out. I can’t say for sure, but if I had to guess, I would say the 1 is telling it that it’s passing one parameter to be printed out.


    1In case you care to verify that, try this:

    #include <stdio.h>
    
    #pragma pack(1)
    struct x {
        long x, y;
    };    
    
    int main() { 
        x v = {0, 1081610240};
    
        printf("%f\n", *(double *)&v);
        return 0;
    }
    

    Officially, of course, this is non-portable, etc., but with the same compiler on the same machine, chances are about 99% that you’ll get the same output I did — 385.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Are they generated by different phases of a compiling process? Or are they just
I process data with two maps per records, one is (&,=)-formatted (id=111&name=...), the other
I am comparing the possibilities for using services (in the sense of a process
Is there any kind of function or quick process for comparing two arrays in
I want to process images to establish say, 9 areas inside each one, then
I am in the process of researching/comparing CXF and Spring-WS for web services? I
I have a question about comparing UIImages in Objective-C when one image has already
I'm having some problems with g++ and the compiling process for a C/C++ program
Will the following program cause any problem during compiling and execution process? class A{
Process process = new Process(); ProcessStartInfo psi = new ProcessStartInfo(@C:/PsExec.exe); psi.UseShellExecute = false; psi.RedirectStandardOutput

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.