Jump to content



# returned variables-C++


theoamd

Recommended Posts

Αν μου επιτρέπεις την παρατήρηση, πάλι γίνεσαι απόλυτος:

δεν υπάρχει κανένα (μα κανένα) πλεονέκτημα

Τα στοιχεία μιας γλώσσας προγραμματισμού (πχ variables) υπάρχουν για να εξυπηρετήσουν ανάγκες.

Όπως αναφέρεις κι εσύ, η κακή χρήση τους από τον ανθρώπινο παράγοντα είναι αυτή που δημιουργεί τα bugs, και όχι τα ίδια τα στοιχεία.

Το παραπάνω (δηλ. η κακή χρήση) ισχύει βέβαια και για άλλα επιτεύγματα του ανθρώπινου πολιτισμού.

Link to comment
Share on other sites

δεν υπάρχει κανένα (μα κανένα) πλεονέκτημα για global/static μεταβλητές στους σύγχρονους compilers όταν υπάρχουν εναλλακτικές

Όταν κάνεις παράθεση κάτι, πρέπει να την κάνεις χωρίς να αλλοιώνεις το νόημα.

Ναι, υπάρχουν περιπτώσεις που αυτού του είδους οι μεταβλητές είναι χρήσιμες και ο μοναδικός τρόπος να υλοποιήσεις κάτι. Όχι, η περίπτωση του OP δεν είναι μία από αυτές. Το ίδιο ισχύει για όλα τα χαρακτηριστικά μιας γλώσσας.

Link to comment
Share on other sites

Όλες αυτές οι δυνατότητες δεν υπάρχουν τυχαία στους compilers, το ότι δεν μπορούν οι περισσότεροι να γράψουν κώδικα, δεν σημαίνει ότι είναι κακές πρακτικές... Οι static μεταβλητές είναι εξαιρετικά χρήσιμες και οι global το ίδιο και ειδικά με αυτές μπορείς να γράψεις optimized κώδικα από άποψη ταχύτητας...

Ακόμα και η goto που λανθασμένα λένε ότι δεν πρέπει να χρησιμοποιείται, λύνει έξυπνα πολλά προβλήματα και μπορεί να κάνει πολύ πιο optimized κώδικα απ' ότι να γράφεις ένα σωρό κώδικα για να αποφύγεις την χρήση της...

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

Link to comment
Share on other sites

Δύο απλά παραδείγματα:


/* test_g.c */
#include <stdio.h>

int i = 0;

void foo(void) { ++i; }

int main(void)
{
foo();
printf("%d\n", i);
return 0;
}

και


/* test_ng.c */
#include <stdio.h>

void foo(int* j) { ++(*j); }

int main(void)
{
int i = 0;
foo(&i);
printf("%d\n", i);
return 0;
}

Βήμα δεύτερο:


$ gcc --version
gcc (GCC) 4.7.1 20120614 (XXXX)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -O3 -Wall -S test_g.c -o test_g.s ; gcc -O3 -Wall -S test_ng.c -o test_ng.s ; diff test_g.s test_ng.s
1c1
< .file "test_g.c"
---
> .file "test_ng.c"
8c8
< addl $1, i(%rip)
---
> addl $1, (%rdi)
23c23
< movl i(%rip), %esi
---
> movl $1, %esi
26,27d25
< addl $1, %esi
< movl %esi, i(%rip)
35,41d32
< .globl i
< .bss
< .align 16
< .type i, @object
< .size i, 4
< i:
< .zero 4

Με εξαιρετικά απλό παράδειγμα, ήδη έχεις μια addl και μία movl παραπάνω. Γιατί οι global και static είναι στο data segment του προγραμματός σου.

Και αν δεν αρκεί αυτό σαν παράδειγμα, σε μεγαλύτερους κώδικες, οι global / static μεταβλητές θα σου κλείσουν τις περισσότερες φορές το vectorization, inlining, constant propagation, loop fusion/coallescing κλπ (εκτός και αν είναι read-only). Και αυτό μπορεί να σημαίνει μέχρι και 3x πιο αργό εκτελέσιμο αν τύχει οι χαμένες βελτιστοιποιήσεις να είναι στο κρίσιμο μονοπάτι του κώδικα.

Για να βάλω και το OpenMP / threads στο παιχνίδι, η static / global θέλει ένα critical section γύρω της, ώστε να αποφευχθούν data races. Αυτό σημαίνει ότι μόλις δημιουργήθηκε ένα thread contention point - πάει το scalability.

Τέλος, τις περισσότερες φορές οι global / static θα προκαλέσουν και cache misses.

Αν ακόμα επιμένετε ότι είναι καλή ιδέα να χρησιμοποιείς global / static, μου τελείωσαν τα επιχειρήματα.

ΥΓ όπως είπα παραπάνω, κάποια προβλήματα λύνονται μόνον με global μεταβλητές. Αλλά τότε τις κάνεις και static ώστε να χρησιμοποιούνται μόνον από το συγκεκριμένο compilation unit, ώστε να έχεις τα optimizations σου και να ελαχιστοποιείς τα cache misses.

Link to comment
Share on other sites

Το είπα παραπάνω:

Ναι, υπάρχουν περιπτώσεις που αυτού του είδους οι μεταβλητές είναι χρήσιμες και ο μοναδικός τρόπος να υλοποιήσεις κάτι. Όχι, η περίπτωση του OP δεν είναι μία από αυτές. Το ίδιο ισχύει για όλα τα χαρακτηριστικά μιας γλώσσας.

Τίποτα δεν είναι κακό. Αλλά τα πάντα δεν είναι καρφί επειδή ξέρεις να χρησιμοποιείς μόνον το σφυρί.

Link to comment
Share on other sites

Συμφωνώ απόλυτα με το παραπάνω (και όχι με το 1 του post #11).

Μια και αρχίσαμε αυτή τη κουβέντα, κι επειδή βρίσκομαι μακρυά από το χώρο μου, μπορείς να δεις το assembly output που θα προκύψει, αν στο post #25 αλλάξεις την θέση του ++ operator στις συναρτήσεις foo ? Έχεις την δυνατότητα να δοκιμάσεις κι άλλον compiler εκτός του gcc ?

Link to comment
Share on other sites

Ακριβώς το ίδιο αποτέλεσμα αν χρησιμοποιείς post-increment - ούτως ή άλλως δε υπάρχει ανάθεση, οπότε το αποτέλεσμα είναι το ίδιο.

Ο clang 3.0 παράγει παραπλήσιο κώδικα με τον gcc. Μόνον ο intel κατάφερε να παράξει το ίδιο εκτελέσιμο και στις δύο περιπτώσεις. Άμα το θυμηθώ, Δευτέρα μπορώ να χρησιμοποίσω τον Cray compiler και PGI.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Δημιουργία...

Important Information

Ο ιστότοπος theLab.gr χρησιμοποιεί cookies για να διασφαλίσει την καλύτερη εμπειρία σας κατά την περιήγηση. Μπορείτε να προσαρμόσετε τις ρυθμίσεις των cookies σας , διαφορετικά θα υποθέσουμε ότι είστε εντάξει για να συνεχίσετε.