Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

migf1 και Directx: Ψηθείτε να ανοίξουμε eshop και να πουλάμε φτηνή μηχανή popcorn με "ειδική προσφορά για μέλη του insomnia". Μπορούμε να βάλουμε και αναψυκτικά και τέτοια.

 

Όποτε έχουμε έξοδα βάζουμε τον Star_Light να κάνει μια αθώα ερώτηση και με κανα δυο ωρίτσες ενασχόληση ο καθένας έχουμε γίνει.

Δημοσ.

migf1 και Directx: Ψηθείτε να ανοίξουμε eshop και να πουλάμε φτηνή μηχανή popcorn με "ειδική προσφορά για μέλη του insomnia". Μπορούμε να βάλουμε και αναψυκτικά και τέτοια.

 

Όποτε έχουμε έξοδα βάζουμε τον Star_Light να κάνει μια αθώα ερώτηση και με κανα δυο ωρίτσες ενασχόληση ο καθένας έχουμε γίνει.

Καλό ;)

Δημοσ.

Γιατί όταν ο J. Random Programmer πάει να υλοποιήσει κρυπτοσύστημα πιάνει την πρώτη rand() που θα βρει μπροστά του και τη χρησιμοποιεί για τα πάντα, με καταστροφικά αποτελέσματα. Αν έλεγες "το ευκολότερο είναι να χρησιμοποιείς CRNG παντού" δε θα σχολίαζα. Το "πρέπει να χρησιμοποιείς CRNG παντού" όμως είναι λάθος και γι' αυτό το σχολίασα. Πολύ ευγενικά και καλόπιστα (στην αρχή).

Disclaimer: Εκτιμώ τις γνώσεις και του defacer και του DirectX και πιστεύω ξέρουν περισσότερα από εμένα στο θέμα. Έχω ασχοληθεί με τους κώδικες προγραμμάτων όπως gnupg, κτλ αλλά δεν έχω γράψει μόνος μου κάποιο σοβαρό κρυπτοσύστημα πέρα από τις κλασικές χαζομαρίτσες όπως υλοποίηση του τάδε και του δείνα αλγορίθμου.

 

Αν και δεν μαρέσουν οι απόλυτες απόψεις και έχω διαφωνίσει σε επιχειρήματα τύπου "μην χρησιμοποιείτε ποτέ goto" και τέτοια, στην προκειμένη περίπτωση θα πω κάτι πιο ακραίο από το "να χρησιμοποιείς παντού crng". Αυτό που προτείνω είναι "Μην υλοποιείς RNG". Τα μαθηματικά είναι δύσκολα και είναι πολύ εύκολο να ξεφύγει κάτι όπως το φιάσκο του debian, οι αδυναμίες του DSA, κτλ. Όπως είπε και το κογιότ σε ένα επεισόδιο "Άσε να το κάνει κάποιος που ξέρει". Υπάρχουν δεκάδες βιβλιοθήκες σε κάθε γλώσσα με αποδεδειγμένα σωστό κώδικα.

Δημοσ.

Καλό ;)

 

Το έχεις καταλάβει ότι εμείς και μερικοί άλλοι είμαστε αυτοί που παράγουν το περιεχόμενο σ' αυτό το forum για το οποίο έρχονται πολλοί άλλοι και δε βγάζουμε δεκάρα απ' αυτό ε;

 

Αν μετακομίζαμε σε private forum και βάζαμε συνδρομή π.χ. 2 ευρώ το μήνα ο imitheos και το παπί χαλαρά θα πλήρωναν.

Δημοσ.

Το έχεις καταλάβει ότι εμείς και μερικοί άλλοι είμαστε αυτοί που παράγουν το περιεχόμενο σ' αυτό το forum για το οποίο έρχονται πολλοί άλλοι και δε βγάζουμε δεκάρα απ' αυτό ε;

 

Αν μετακομίζαμε σε private forum και βάζαμε συνδρομή π.χ. 2 ευρώ το μήνα ο imitheos και το παπί χαλαρά θα πλήρωναν.

 

Και τις μεγάλες διαφωνίες θα τις λύνατε με Arcade Volleyball Challenge

 

Υ.Γ: Αρκετές χαζομάρες είπα για μία ημέρα :) /me crawls back to his cave

Δημοσ.

 

 

 

Γιατί όταν ο J. Random Programmer πάει να υλοποιήσει κρυπτοσύστημα πιάνει την πρώτη rand() που θα βρει μπροστά του και τη χρησιμοποιεί για τα πάντα, με καταστροφικά αποτελέσματα. Αν έλεγες "το ευκολότερο είναι να χρησιμοποιείς CRNG παντού" δε θα σχολίαζα. Το "πρέπει να χρησιμοποιείς CRNG παντού" όμως είναι λάθος και γι' αυτό το σχολίασα. Πολύ ευγενικά και καλόπιστα (στην αρχή).

 

 

Το τι μου φαίνεται είναι υποκειμενικό. Το τι είναι σωστό είναι αντικειμενικό. Λέω "μου φαίνεται" γιατί α) είμαι άνθρωπος και μπορεί να κάνω λάθος και β) το αντίθετο θα ήταν ένδειξη μη σεβασμού προς το συνομιλητή μου. Εγώ από μέσα μου μπορεί να πιστεύω ότι έχω τόσο δίκιο όσο και ο Αριστείδης (ο Δίκαιος), αλλά δε γίνεται να κατεβώ μ' αυτό σαν επιχείρημα.

 

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

 

Τέλος, αν προσέξεις θα δεις ότι δεν έχω διαφωνήσει με το περιεχόμενο των άρθρων (χωρίς να το αποκλείω για το μέλλον, αλλά μέχρι τώρα δε μου έχει κάνει κανείς quote σκουπίδια). Έχω διαφωνήσει όμως με τη σχετικότητα των άρθρων πάνω στην κουβέντα και κυρίως με την ερμηνεία που δίνει στα άρθρα ο συνομιλητής μου.

 

 

Δεν έχω καμία αμφιβολία ότι έχεις κάνει όλα αυτά που λες και ακόμα περισσότερα (είναι φανερό από άπειρα threads ότι έχεις μακρόχρονη σταδιοδρομία στο χώρο). Αλλά αυτό δεν είναι επιχείρημα εκτός κι αν μιλάς σε κάποιον με εμφανώς απείρως λιγότερη εμπειρία απο σένα. Υποθετικά μιλώντας, μπορεί να ασχολείσαι 25 χρόνια και να κάνεις 25 χρόνια πατάτες. Δε συνδέονται η ποσότητα και η ποιότητα της δουλειάς.

 

Και γω έχω υλοποιήσει κρυπτοσυστήματα σε C++ πάνω σε bare sockets (όλα manually, ξεκινώντας από Diffie-Hellman). Έχει σημασία; Από πού θα κρίνεις εσύ αν ξέρω τι μου γίνεται, από αυτά που λέω εδώ ή από το πώς δουλεύουν τα προγράμματά μου που δεν τα έχεις δει ποτέ;

 

 

 

Εγώ πάντως φίλε defacer θα ψηνόμουν να έβλεπα λίγο από τον κώδικα σου έστω σε 1 / 1000 topics που σχολιάζεις. Έτσι για την ιστορία... Χωρίς καμία διάθεση πρόκλησης ή εμπαιγμού... Έτσι έστω μία φορά, έτσι για το καλό...

Δημοσ.

Εγώ πάντως φίλε defacer θα ψηνόμουν να έβλεπα λίγο από τον κώδικα σου έστω σε 1 / 1000 topics που σχολιάζεις. Έτσι για την ιστορία... Χωρίς καμία διάθεση πρόκλησης ή εμπαιγμού... Έτσι έστω μία φορά, έτσι για το καλό...

 

Αν βρεθεί κατάλληλη ευκαιρία why not. Δυστυχώς πλέον δε γράφω σχεδόν ποτέ C/C++ οπότε δεν έχω έτοιμα φρέσκα πράγματα, και δεν έχω και χρόνο/θέληση να κάτσω να γράψω κώδικα from scratch. Μια φορά που το έκανα είχε σαν αποτέλεσμα να γράψω αυτό (για το οποίο δεν είμαι ιδιαίτερα περήφανος, από άποψη δομής το θεωρώ barely passable αλλά χωρίς boost για να γίνει κάτι ουσιαστικά καλύτερο θα ήθελε άπειρο "άσχετο" κώδικα).

 

Θα ψηνόμουν να το κάνω revisit σε c++11 αν σ' ενδιαφέρει να το δεις.

 

Update: μπορείς αν θες να κοιτάξεις και στο StackOverflow, κατά καιρούς έχω γράψει μερικά μεγαλύτερα κομμάτια. Κάποια από αυτά είναι άνετα blog material, αλλά θα πρέπει να ψάξεις να τα βρεις.

 

Επίσης έχω GitHub και BitBucket, μπορείς να με κάνεις follow και αν υπάρξει κάτι εκεί (too many ideas, too little time) να το δεις. Υπάρχει αρχαιολιθικός PHP 4 κώδικάς μου στο SourceForge και ακόμα πιο παλιός PHP 4 κώδικας στο Moodle (ήμουν component maintainer την εποχή version 1.4 - 1.6, αν βρεις tarballs από τόσο παλιά πες μου να σου πώ πού να κοιτάξεις).

Δημοσ.

Ψάχνω να δω ποτε μπορει να συμβει αυτο που λες :P

 

 

>

#include <stdio.h>
#define size 2
void foo(int [] , int );

int main(void)
{
int a[2]={0,1} , len;

puts("Πριν το λάθος....");
   foo(a,size);	
	
len=100;

foo(a,len);

   return 0;
}
void foo(int a[] , int len)
{
printf("%d , %d\n" , len , a[len]);

return ;
}
//----------------------------------------------------------------------

 

 

Αυτη ειναι μια πιθανη περιπτωση... αυτην εννοεις???? εδω κανει overflow με UB.

ΑΛλιως το size δεν αλλαζει.... και εκτος αυτου

μολις την καλεις με ορισμα το size γινεται παντα η αντικατασταση της σταθεράς

που εχεις ορισει εξαρχης και απο τις πρωτες πριν ακομη αποκτησεις τον πονοκεφαλο του προτζεκτ

αρα ηξερες τι εκανες.... εχω αδικο? Υπάρχει άλλη περίπτωση??? Εχεις κανα ευκαιρο παραδειγμα ?

 

EDIT: Εκτος και αν αλλαξει τοπικα με καποιο τροπο το len μεσα στην συνάρτηση και πας μετα να προσπελάσεις τα στοιχεια του πίνακα με αυτην σαν μήκος.

 

EDIT2: Μαλλον κατι τετοιο εννοεις γιατι ξαναβλεπω το αρχικο σου ποστ που λεει οτι αν περασεις αντικανονικη τιμη στην συνάρτηση.... δεδομενου οτι μια defined δεν μπορει να αλλαξει επομενως δεν μιλάς καθολου για αυτην. Κατι τετοιο εννοεις χοντρικα σαν το παραδειγμα που εφτιαξα....

Σε τόσο loosely ruled γλώσσες όπως η C μπορεί να αποδειχτεί έως και πολύτιμη η προσπάθεια ελαχιστοποίησης ενδεχομένων σφαλμάτων. Προς σε αυτή την κατεύθυνση "βαδίζουν" και τα διάφορα coding standards, αλλά και κάποιες "τεχνικές" συγγραφής κώδικα που έχουν αναπτυχθεί μέσα στο πέρασμα του χρόνου. Όπως συμβαίνει όμως συνήθως, είναι κι αυτά trade-offs έναντι άλλων χρήσιμων χαρακτηριστικών (π.χ. του readability).

 

Ο "λιτός" τρόπος που περιέγραψα παραπάνω μειώνει σε πολύ μεγάλο βαθμό τα έστω και κατά λάθος σφάλματα, και μάλιστα με τις λιγότερες δυνατές ανάγκες για έξτρα ελέγχους.

 

Δεν χρειάζεται να κάνεις κανενός είδους έλεγχο μέσα στη foo() ούτε να περάσεις έξτρα ορίσματα που ο μόνος τους σκοπός είναι ο έλεγχος για αποτροπή σφαλμάτων.

 

Τον ξαναγράφω εδώ για να τον εξηγήσω λίγο καλύτερα...

 

>
#define MAXELEMS  100

void foo( int arr[] )
{
for (int i=0; i < MAXELEMS; i++)
		...
}

int main( void )
{
int arr[ MAXELEMS ] = {0};
...
foo( arr );
...
}

Από τη στιγμή που ορίζεις το MAXELEMS, αν από εκεί και πέρα το χρησιμοποιείς με συνέπεια ως alias όπου χρειάζεσαι την τιμή του τότε μειώνεις δραματικά την ανάγκη να για έξτρα ελέγχους, που με τη σειρά του σημαίνει και λιτό κώδικα (που με τη σειρά του στο έμπειρο μάτι σημαίνει πιο ευανάγνωστο κώδικα).

 

Στον παραπάνω κώδικα ότι θετική τιμή και να βάλεις αρχικά στο #define δεν υπάρχει περίπτωση να δημιουργηθεί buffer-overrun στο arr (προφανώς για νούμερο εντός της τρέχουσας stack). Είναι επίσης πολύ λιτός ο κώδικας, καθώς και γρήγορος, με το λιγότερο δυνατό overhead. Ευανάγνωστος επίσης.

 

Ακόμα κι αρνητική τιμή να του δώσεις στον ορισμό του, δεν έχεις πρόβλημα γιατί δεν θα περάσει καν από τον compiler. Το ότι η foo() παίρνει ως όρισμα μόνο το arr εξασφαλίζει πως δεν προκύπτει ανάγκη ελέγχου για buffer overrun γιατί ο κώδικάς της δεν έχει απολύτως καμία εξάρτηση από κάποιο user-defined όρισμα κατά την κλήση της

 

Σημαίνει επίσης πως μπορείς να κρύψεις τελείως τον κώδικα της foo() και να την διαθέσεις για public χρήση χωρίς να χρειάζεται καν να γνωρίζει ο προγραμματιστής που θα την χρησιμοποιήσει ποιο είναι το όριο στοιχείων του arr προκειμένου να το περάσει ως όρισμα στη συνάρτηση (ούτε καν το alias του). Ακόμα και για σένα τον ίδιο, σημαίνει πως δεν χρειάζεται να θυμάσαι το όριο στοιχείων του arr κάθε φορά που θέλεις να καλέσεις τη συνάρτηση.

 

Με λίγα λόγια είναι μια πολύ efficient και ασφαλής υλοποίηση.

 

Όταν περνάς το μήκος ως όρισμα, συνήθως δεν το θέλεις μόνο για να ελέγχεις πιθανά buffer overruns, αλλά και για άλλες δουλειές (δεν μου έρχεται τώρα πρόχειρα στο μυαλό κάποια που να σχετίζεται με στατικούς πίνακες, υπάρχουν σίγουρα όμως). Σε αυτή την περίπτωση, επειδή η συνάρτηση δεν μπορεί να ξέρει τι θα της περάσει ως όρισμα ο προγραμματιστής, είναι καλό (good practice) να ελέγχει αν το όρισμα είναι μέσα στο επιθυμητό εύρος τιμών πριν το χρησιμοποιήσει.

 

Αλλιώς ο έλεγχος αυτός θα πρέπει να γίνεται έξω από την συνάρτηση για το όρισμα που θα της περαστεί, μετατίθεται δηλαδή ένα level πάνω, στον caller. Αν λοιπόν η foo() είναι για παράδειγμα μια public συνάρτηση μιας βιβλιοθήκης, χωρίς το συγκεκριμένο έλεγχο μέσα της δεν μπορεί να εγγυηθεί την ομαλή λειτουργία του κώδικά της.

 

Χωρίς κανένα έλεγχο για το όρισμα (ούτε έξω, ούτε μέσα στη συνάρτηση) τότε ρισκάρουμε την περίπτωση που έστω και κατά λάθος της περαστεί αντικανονική τιμή.

 

ΥΓ. Στον κώδικά σου, το

#define size 2

 

και το..

int arr[ 2 ];

are looking for trouble ;)

 

 

 

 

Perfect Popcorn Recipe

  • Cook time: 10 minutes

Add to shopping list

Ingredients

  • 3 Tbsp canola, peanut or grapeseed oil (high smoke point oil)
  • 1/3 cup of high quality popcorn kernels
  • 1 3-quart covered saucepan
  • 2 Tbsp or more (to taste) of butter
  • Salt to taste

Method

1 Heat the oil in a 3-quart saucepan on medium high heat.

 

2 Put 3 or 4 popcorn kernels into the oil and cover the pan.

 

3 When the kernels pop, add the rest of the 1/3 cup of popcorn kernels in an even layer. Cover, remove from heat and count 30 seconds. (Count out loud; it's fun to do with kids.) This method first heats the oil to the right temperature, then waiting 30 seconds brings all of the other kernels to a near-popping temperature so that when they are put back on the heat, they all pop at about the same time.

 

4 Return the pan to the heat. The popcorn should begin popping soon, and all at once. Once the popping starts in earnest, gently shake the pan by moving it back and forth over the burner. Try to keep the lid slightly ajar to let the steam from the popcorn release (the popcorn will be drier and crisper). Once the popping slows to several seconds between pops, remove the pan from the heat, remove the lid, and dump the popcorn immediately into a wide bowl.

 

With this technique, nearly all of the kernels pop (I counted 4 unpopped kernels in my last batch), and nothing burns.

 

5 If you are adding butter, you can easily melt it by placing the butter in the now empty, but hot pan.

 

6 Salt to taste.

 

Additional tips: From the comments section

 

a If you add salt to the oil in the pan before popping, when the popcorn pops, the salt will be well distributed throughout the popcorn.

 

b Fun toppings for the popcorn - Spanish smoked paprika, nutritional yeast, cayenne powder, chili pepper, curry powder, cumin, grated Parmesan cheese.

 

Yield: Makes 2 quarts, a nice amount for two people, or for one hungry one.

 

 

 

 

Δημοσ.

Ωραία :D αν και ξερεις αμα δεν το δω στην πράξη

συνεχιζω να αναρωτιέμαι για ποιο λογο θα μπορουσε ο προγραμματιστης

να περάσει μια τιμή μήκους πίνακα σαν όρισμα η οποια δεν ειναι αυτη που έχει οριστει

εξαρχής με την #define για αυτη τη δουλειά. Και ετσι δεν θα ανησυχουσαμε ουτε για ελεγχους ουτε για τιποτα... το 2ο ορισμα θα αντιστοιχουσε με τη μια στο #define MAXELEMS some_value . Οποτε τι σε εμποδιζει μετα καθε κληση να την κάνεις με MAXELEMS.

 

Η συνάρτηση μπορει να μην ξέρει τι της περνάς εσυ ομως ξέρεις!!! Και θυμάμαι ακομη και αν σε άλλους κώδικες ειχαμε βάλει 2ο ορισμα το μήκος δεν παίζαμε μεσα με κανέναν έλεγχο.

Δημοσ.

Ωραία :D αν και ξερεις αμα δεν το δω στην πράξη

συνεχιζω να αναρωτιέμαι για ποιο λογο θα μπορουσε ο προγραμματιστης

να περάσει μια τιμή μήκους πίνακα σαν όρισμα η οποια δεν ειναι αυτη που έχει οριστει

εξαρχής με την #define για αυτη τη δουλειά. Και ετσι δεν θα ανησυχουσαμε ουτε για ελεγχους ουτε για τιποτα... το 2ο ορισμα θα αντιστοιχουσε με τη μια στο #define MAXELEMS some_value .

Να σου δώσω ένα πολύ απλοϊκό παράδειγμα, μόνο και μόνο για να το δεις σε μορφή κώδικα...

 

>
#define SIZE 100
...
int main( void )
{
int arr[ SIZE ] = {0};
   ...
int size = 1000;   // ενδεχομένως δεν αναφέρεται καν στο arr, αλλά ίσως σε κάποιον άλλον πίνακα., πιθανότατα dynamic.
  ...
  // πολύ αργότερα....
foo( arr, size );   // κατά λάθος αντί για SIZE πέρασα size
  // !!!ΒΟΟΜ!!!
  ...

Δημοσ.

Να σου δώσω ένα πολύ απλοϊκό παράδειγμα, μόνο και μόνο για να το δεις σε μορφή κώδικα...

 

>
#define SIZE 100
...
int main( void )
{
int arr[ SIZE ] = {0};
   ...
int size = 1000;   // ενδεχομένως δεν αναφέρεται καν στο arr, αλλά ίσως σε κάποιον άλλον πίνακα., πιθανότατα dynamic.
  ...
  // πολύ αργότερα....
foo( arr, size );   // κατά λάθος αντί για SIZE πέρασα size
  // !!!ΒΟΟΜ!!!
  ...

 

:lol: :lol: δηλαδή οριζεις μια ακέραιη μεταβλητή φαινομενικά άσχετη με το πινακα....

και μπορει να γινει αυτη η μλκια :P . Νταξει οκ !!! Τωρα το κατάλαβα :P

 

Και τι BOOM Βασιλικό *BOOM* !!!! έβαλες και 1000 , 100 φορες πάνω απο το ηδη declared μήκος του πινακα σου :lol:

Δημοσ.

:lol: :lol: δηλαδή οριζεις μια ακέραιη μεταβλητή φαινομενικά άσχετη με το πινακα....

και μπορει να γινει αυτη η μλκια :P . Νταξει οκ !!! Τωρα το κατάλαβα :P

Σε μεγάλα projects δεν είναι καθόλου δύσκολο να την πατήσεις κάπως έτσι. Για αυτό και μιλάμε για good και bad practices, τα οποία μπορεί στις απλές ασκήσεις να μη φαίνεται η σημασία τους, αλλά σε μεγάλα projects αποκτούν ολοένα και μεγαλύτερη σημασία. Αν εντυπωθούν εξαρχής bad practices, αυξάνονται οι πιθανότητες εμφάνισης δυσεύρετων bugs όσο μεγαλώνει ο κώδικας.

 

Στο παραπάνω παράδειγμα, το int size μπορεί να μην είναι καν ορισμένο στο ίδιο αρχείο με την σταθερά SIZE. Για τον ίδιο λόγο είναι σημαντικό να εντυπώσει κανείς εξαρχής good-practices ακόμα και στη μεθοδολογία ονομασίας των μεταβλητών, συναρτήσεων, σταθερών, κλπ που χρησιμοποιεί.

 

EDIT:

 

Ξέχασα, ακόμα και σε αυτό το μπακαλο-παράδειγμα μπορείς να αποφύγεις το BOOΜ είτε υλοποιώντας την foo() με τον λιτό τρόπο, είτε με τον περιφραστικό, με την προϋπόθεση πως στον περιφραστικό κάνεις έλεγχο μέσα στον κώδικά της συνάρτησης για να είναι το όρισμα στο επιθυμητό εύρος τιμών πριν το χρησιμοποιήσεις.

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

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