Πόσο καλά τα πάει ο gcc με τα templates;

Giorgos Keramidas keramida at ceid.upatras.gr
Tue May 2 18:30:23 EEST 2006


On 2006-05-02 17:54, Chameleon <cham_gss at hotmail.com> wrote:
> Μπα. Μάλλον είναι αδύνατο να ξαναγυρίσω πάλι στη C. Δεν βολεύει για
> πολύ κώδικα. Βασικά δεν βολεύει για πολλά πράγματα.
>
> "Η C είναι η γλώσσα προγραμματισμού με την οποία προγραμμάτισε ο Θεός
> τον κόσμο"
> "Η C++ είναι η γλώσσα προγραμματισμού των αιρετικών"
> ... από το "OpenGL Programming Guide" στο Glossary.

Αντίστοιχης 'εξυπνάδας' σχόλιο με την πανέμορφη αλλά εξίσου λάθος γνώμη
του Strousstrup για το πνευματικό του παιδί...  Τέλος πάντων.

> >> Μεταξύ μας, δεν έχω πάρει ιδέα ποιά είναι η διαφορά μεταξύ gcc, g++
> >> και c++.  Όλα το ίδιο δεν κάνουν;
> >
> > Οχι.
> > Το `gcc' είναι C compiler.
>
> πλάκα μου κάνεις τώρα; Και πως έκανα compile κώδικα c++ με gcc;
> α! έτσι εξηγείται που δεν μπορούσα να παράγω εκτελέσιμο! (τα .ο
> παράχθηκαν κανονικά!)

Ναι έτσι εξηγείται.  Το GNU C Compiler suite έχει και C++ runtime
βιβλιοθήκες και C runtime βιβλιοθήκες.  Προσοχή τι του λες να κάνει,
γιατί θα σε υπακούσει τυφλά, ακόμα κι αν του λες κάτι λάθος :P

> δε μου λες; γιατι είναι τοσο huge (500KBs) ενώ στα Windows είναι τόσο
> small; Κι επειδή πάει και αργά, μάλλον έχει ενσωματώσει debug symbols.

Οχι, γενικά η C++ είναι πιθανόν να παράγει λίγο πιο χάλια εκτελέσιμα.
Ακόμη και σε απλά προγράμματα όπως το "Hello world" μπορεί να δεις
διαφορά, αλλά όχι τόσο μεγάλα binaries όπως λες:

  1 |    #include <iostream>                 |    #include <stdio.h>
  2 |    #include <iomanip>                  |
  3 |                                        |    int
  4 |    using namespace std;                |    main(void)
  5 |                                        |    {
  6 |    int                                 |        printf("Hello world\n");
  7 |    main(void)                          |        return 0;
  8 |    {                                   |    }
  9 |        cout << "Hello world" << endl;  |
 10 |        return 0;                       |
 11 |    }                                   |

Μπορείς να τα κάνεις αυτά build με σχετικά μικρό optimization level:

    $ cc -O2 -W -Wall -std=c99 -pedantic -o c-hello hello.c
    $ c++ -O2 -W -Wall -o cc-hello hello.cc

Οταν τρέχουν αυτά τα 2, οι χρόνοι είναι λίγο υπέρ της C:

    $ /usr/bin/time /bin/sh -c 'count=0; \
          while test $count -lt 1000 ; do \
         ./c-hello >/dev/null ; count=$(( $count + 1 )) ; done'
            5.06 real         0.82 user         4.21 sys
    $ /usr/bin/time /bin/sh -c 'count=0; \
          while test $count -lt 1000 ; do \
          ./cc-hello >/dev/null ; count=$(( $count + 1 )) ; done'
            9.81 real         3.08 user         6.64 sys

> Πως μπορώ να παράγω μια πολύ "release" έκδοση; (χωρίς debug symbols)

Με strip(1) στα εκτελέσιμα:

    $ ls -l c-hello cc-hello
    -rwxrwxr-x  1 giorgos  giorgos  - 7414 May  2 18:04 c-hello
    -rwxrwxr-x  1 giorgos  giorgos  - 8607 May  2 18:04 cc-hello
    $ strip --strip-all c-hello cc-hello
    $ ls -l c-hello cc-hello
    -rwxrwxr-x  1 giorgos  giorgos  - 3004 May  2 18:14 c-hello
    -rwxrwxr-x  1 giorgos  giorgos  - 3804 May  2 18:14 cc-hello
    $

Πιστεύω 3 ΚΒ είναι πιο λογικό μέγεθος.  Μόνο 25% μεγαλύτερο είναι
περίπου το binary της C++ τελικά.

> το makefile είναι αυτό:
> -----------------------
> VPATH = ../src ../example
>
> example1d:	wastage1d.o example1d.o
> 	g++ -o example1d wastage1d.o example1d.o
> wastage1d.o:	wastage1d.cpp wastage1d.h
> 	g++ -c $< -o $@
>
> example1d.o:	example1d.cpp wastage1d.h
> 	g++ -c $< -o $@
> -----------------------

Μην βάζεις 'hardcoded' τιμές σε compiler & flags, γιατί όταν μια μέρα θα
θες να το αλλάξεις αυτό θα βλαστημάς την βιασύνη που σε έκανε να το
γράψεις έτσι.  Ενας παλιός κανόνας για makefile writers λέει:

    ``Οταν κάτι εμφανίζεται πάνω από μια φορά, είναι ώρα να το κάνεις
    μεταβλητή.''

Εγώ θα το 'γραφα κάπως έτσι:

     1  progname = cc-hello
     2  exe_ext =
     3
     4  prog = $(progname)$(exe_ext)
     5
     6  $(progname)_sources = foo.cc
     7  $(progname)_objs = $(patsubst %.cc,%.o,${$(progname)_sources})
     8  objs = ${$(progname)_objs}
     9
    10  strip_program = strip
    11  strip_flags = --strip-all
    12  strip_cmd = $(strip_program) $(strip_flags)
    13
    14  ifeq ($(CCC),)
    15  CCC = c++
    16  endif
    17
    18  ifeq ($(CCCFLAGS),)
    19  CCCFLAGS = -O2 -W -Wall
    20  endif
    21
    22  all: $(prog)
    23
    24  clean:
    25          -/bin/rm -f $(objs)
    26
    27  realclean: clean
    28          -/bin/rm -f $(prog)
    29
    30  $(prog): $(objs)
    31          $(CCC) $(CCCFLAGS) -o $@ $(objs) $(LDFLAGS) $(LDADD)
    32          $(strip_cmd) $@
    33
    34  %.o: %.cc
    35          $(CCC) $(CCCFLAGS) -o $@ -c $^

Ετσι μπορείς να γράψεις π.χ.:

    $ gmake realclean
    /bin/rm -f foo.o
    /bin/rm -f cc-hello
    $

Να κάνεις build με τα 'default' options:

    $ gmake
    c++ -O2 -W -Wall -o foo.o -c foo.cc
    c++ -O2 -W -Wall -o cc-hello foo.o
    strip --strip-all cc-hello
    $

ή με άλλα options, προσωρινά, που σε βολεύουν εκείνη τη στιγμή:

    $ gmake realclean
    /bin/rm -f foo.o
    /bin/rm -f cc-hello
    $ env CCC=g++ CCCFLAGS='-O2' gmake
    g++ -O2 -o foo.o -c foo.cc
    g++ -O2 -o cc-hello foo.o
    strip --strip-all cc-hello
    $

> Όχι ρε φίλε. Η C++ είναι καλή και αναντικατάστατη.

Μια απίστευτη μπούρδα μεγαλειώδους μεγέθους είναι, αλλά λέμε τώρα.




More information about the Linux-greek-users mailing list