CS-332 Gerbessiotis, Alex      August 21, 2026  
------------------------------------------------
Note: If you see reference to a Readme1st.txt
      or just Readme1st it is this file
      named Readmej1.txt and the 1 is a reference
      to Subject 1.


  COMPILING and RUNNING C  programs
  --------------------------------------

This relates to files named 
    one.c two.c three.c four.c five.c six.c etc.

To compile a file eg one.c using the gcc toolchain
   and its C compiler

  a. Identify first the version of gcc compiler you
     plan to use and record this information.
     Identify the version  with
     % gcc -v
    and read the last line that prints  the version#.
    If i do so the last line i get reads like
gcc version 11.4.1 20230605 (Red Hat 11.4.1-2) (GCC) 
    I am thus using version 11.4.1 of gcc.

    As noted in j0src / Readmej0.txt
     % 
    is the command  prompt I am using in the bash shell.
    For you it might be different. You do not type it,
    it gets displayed by bash. In the example above
    you should type gcc -v
    (there is a space in between gcc and -v).
    And do not forget to press the Enter button of the 
    keyboard at the end if you expect the bash shell to
    interpret your command and execute it!

  b. Type as needed
    % gcc one.c -o one
     -o specifies that a non-default executable file
    name will be used, that follows -o after a whitespace
    and is the file with filename (alias) one.
    (If -o one is not specified the name of the 
     executable would be a.out) Thus
    % gcc one.c
      uses a.out as the name of the executable file
      since -o was omitted

    If you cryptographically compare both executables
    % md5sum one a.out
    it is confirmed that
    a.out and one have identical
    cryptographic fingerprints 
    (i.e. they are likely the same).

  c. Type as needed
    % ./one
    to execute the file
    ./ indicates or reads "in the current directory
       find the file that follows (i.e. one) and
       run it (create a process whose code is the code
       of file one. Current directory is the output
       of the command pwd.
       If there is no such executable in your directory 
       an error message will appear.
  d. Type as needed
    % echo $?
     captures and prints the return value 
     of the main function of the executable file one.
     The command echo needs to be typed IMMEDIATELY 
     after the ./one.
     Even the inclusion of a
     % 
     (an empty line generated by pressing the Enter key)
     will disrupt the intended purpose of echoing
     echo $?
     If done properly a 32 is reported as the output
     of echo $? The last line of the main function of
     one.c contains a return(32)!

----------------------------------------------------
  More pedantic information follows.

1. Program  one.c  example

 It is a hello CS332 world program with a twist.

 It returns a nonzero value; this is the value returned
 by the main function.
   a. ENTRY POINT of a C/C++/Java function
      The entry point of  one.c is indicated in one.c 
      by a function of a special name:  main
   b. RETURN VALUE OF MAIN (C or C++)
      When the main function completes its execution it 
      returns a value: 0 means regular termination, no problem. 
      Another value might indicate something else: an error.

   c. This return value is returned to the OS and is captured
      by the OS and made available to the person who started
      the execution of the executable assiciated with one.c

   NOTE: This discussion applies to C or C++
         The prototype for main should be
         int  main(void)
     or  int  main(int argc, char **argv)

         and never
         void  main(void)
    nor  void  main(int argc, char **argv)


 1.a. Locate the file eg one.c and read it
     % cat  one.c
  or 
     % more one.c 
  allows you to see the source code. If you plan to 
  edit it use a command line editor such as gvim 
  (but read the manual first) or vi or vim.

  Confirm that the return value of the main function is 32.
  (See introduction.)

 1.b. Locate the file eg one.c and compile it

         % gcc one.c -o myone

  Invoke the C compile infrastructure (gcc) and generate
  from the C source file one.c (stored on disk, i.e. seconday
  memory) an executable file name myone also stored on disk.

 1.c. Invoke (Run, Execute) the executable file generated

         % ./myone

 1.d. If you want to inspect the return value returned by the
     main function of myone  (available in one.c) do the
     following IMMEDIATELY AFTER the previous invocation

         % echo $?

 1.e. If everything worked fine this is the sequence of
     steps described and the generated output

% gcc one.c -o myone
% ./myone
Hello CS332 world
% echo $?
32
% 

     We have confirmed the return value of main of one.c
compiled into executable file myone. It is indeed 32 as
display my echo $?. The $? prints the return value of the
more recent execution of the bash shell. In our case it was
./myone



2. Program two.c example

   Repeat with two.c

% gcc two.c -o mytwo
% ./mytwo
Hello CS332 world
% echo $?
76

 You will observe that the return value is 76, yet
in two.c the default return value set through the
global variable i is indicated as 332. The discrepancy
is for one reason. In UNIX and Linux the returned value
is the last (rightmost) 8 bit of the 'intended return value'.
Write down integer 332 in binary, isolate the 8 rightmost bit
and observe that they map to 76. Moreover calculate 332-256
and observe the result.


3. Program three.c example

% gcc three.c -o mythree
% ./mythree
Hello CS332 world
% echo $?
76
% ./mythree 33
Hello CS332 world
% echo $?
33


 three.c is similar to two.c but accepts a command line
 argument. Thus in the second invocation, the 33 is the
 argument passed through the command line to mythree.
 This argument is a string of characters, the digit 3,
 appearing twice. The code converts the string into an
 integer and that integer value (thirty three) is then
 returned as the return value of main.



4. Program four.c example

  Shows how arrays are stored in C ; Connects with Subject 0
  discussion on the topic. Gives an example of confirmation
  of the Little Endian representation of integers in Intel
  architectures.


 5. Program five.c example


  5.a. Variable 

     ivar1 

  is an example of an initialized (global) variable !

  5.b. Variable 

     uvar2 

  is an example of an uninitialized (global) variable !

  5.c. Variables

     svar3, svar4, and svar5

  are examples of stack variables; it does not matter
  whether they are initialized or not.
  Moreover even if svar5 is defined on the stack and space
  for its pointer is allocated on the stack, it points
  to a heap area after the malloc invocation.

  5.d  (int*) malloc(2*sizeof(int));

  (int*) malloc(2*sizeof(int)) allocates space in the
  heap area. Thus the value of svar5 points to an area
  outside of the stack when
   svar5= (int*) malloc(2*sizeof(int));
  is successfully completed.

 6. Program  six.c example

 It is similar to one.c with a twist a function is defined
 in it. The return value of the function stored into variable
 j has no effect to the return value of the executable which is
 the return value of the main() function.

----------------------------
 APPENDIX 


  A. OLD STYLE COMPILATION   



   A.1 Compiler compiles into (readable) assembly
         source   ->  assembly
            .c    ->     .s

         HOW?

         % gcc -S one.c

         VIEW the assembly and be ready to be surprise!

         HOW ?
         % cat one.s



   A.2 Assembler turns assembly source 
       into (unreadable binary) object  code
         assembly ->  object code
            .s    ->     .o
       HOW?

       % as  one.s  -o one1.o  
       (as is the assembler called/invoked directly)
       [We request the output is named one2.o]
   or

       % gcc one.s  -c         
         (gcc calls assembler as indirectly)
         [A file one.o is created]

  [ See A.4 to get an executable file from .s]

 In order to compare one1.o and one.o created do

 % md5sum one.o one1.o
 9d30893f673d7caecf2e8e9b80e62f90  one.o
 9d30893f673d7caecf2e8e9b80e62f90  one1.o

 [one.o and one1.o might generate different but same
  fingerprints if a different compiler/as is being
  used thus contents of one.o and one1.o are 
  different from the ones I generated above.]
 Thus
 The fingerprints of the two files 
        would be the same 
 even if they 
        are different 
 from the fingerprints shown above.



   A.3 Linker links machine code of user program to 
       OS libraries that contain system (function) 
       calls for I/O and other OS provided functionality

         object code + libraries  -> executable code
          one.o                   -> myone
          one1.o                  -> myone1

 % gcc one.o  -o  myone
 % gcc one1.o -o  myone1
 
 and if in doubt
 %  md5sum myone myone2
bdfce413f283a9ec7c34018e34638f86  myone
bdfce413f283a9ec7c34018e34638f86  myone2


 A.4 Assembly into executable 
            .s    ->     executable
         one.s    ->     myone2

       HOW?

       % gcc one.s -o myone2



 
  A.5. DISASSEMBLY : look into object files, exec files

  % objdump -D one.o
  % objdump -D one2.o

  or dump into a file by redirecting output

  % objdump -D one.o  >file1.txt
  % objdump -D one2.o >file2.txt

  Files almost identical; Capture differences

  % diff file1.txt file2.txt 

  And of course

  % objdump -D myone
