Toon posts:

[C] rariteiten

Pagina: 1
Acties:

Verwijderd

Topicstarter
Een van de leuke dingen van C is dat je jezelf behoorlijk in de vingers kan snijden. Zelf heb ik altijd veel lol (en hou ik m'n kennis op peil) van rubrieken waarin de ‘rariteiten’ van C worden besproken. Om maar meteen het goede voorbeeld te geven hier, een kleine uitdaging: volgens onderstaande code is –1 groter dan 1….ra ra hoe kan dat

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main(int argc, char* argv[])
{
    int a          = -1;
    unsigned int b =  1;
    if( a > b )
    {
        printf("a(%d) is groter dan b(%d)\n",a,b);
    }
    else
    {
        printf("a(%d) is kleiner dan b(%d)\n",a,b);
    }
    return 0;
}

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Die signed -1 zal wel gecast worden tot een unsigned 65535 ofzo.

Who is John Galt?


  • Dawai
  • Registratie: December 2000
  • Laatst online: 08-07 23:56

Dawai

HERiTAGE CHESS CREW

Ik gok dat a bij de vergelijking ook als unsigned wordt beschouwd, en dus eigenlijk gelijk is aan 4294967295 ;)

rariteit.c(7) : warning C4018: '>' : signed/unsigned mismatch

edit:
65535 of 4294967295 zal wel afhangen van het platform.

[ Voor 45% gewijzigd door Dawai op 19-09-2003 21:33 ]

Programmer: red-eyed, mumbling mammal capable of conversing with inanimate objects.


  • Exirion
  • Registratie: Februari 2000
  • Laatst online: 04:45

Exirion

Gadgetfetisjist

justmental schreef op 19 September 2003 @ 21:20:
Die signed -1 zal wel gecast worden tot een unsigned 65535 ofzo.
Zoiets, maar int is 32-bits dus 2^32-1 :)

"Logica brengt je van A naar B, verbeelding brengt je overal." - Albert Einstein


  • Emmeau
  • Registratie: Mei 2003
  • Niet online

Emmeau

All your UNIX are belong to us

code:
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(int argc, char* argv[]();
{
   int a=0;
   int b=1;

   a ^= b ^= a ^= b;

   (void)printf("a=%d b=%d\n",a,b);
}


erg leuk. nog leuker is om te zien wat Gcc er van maakt in assembly met -O3

If you choose to criticise you choose your enemies


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Emmeau schreef op 19 september 2003 @ 21:23:
code:
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(int argc, char* argv[]();
{
   int a=0;
   int b=1;

   a ^= b ^= a ^= b;

   (void)printf("a=%d b=%d\n",a,b);
}


erg leuk. nog leuker is om te zien wat Gcc er van maakt in assembly met -O3
Wat is daar leuk aan? Het is gewoon een XORswap.
[edit]
A = a, B = b
A = a XOR b, B = b //a^=b
A = a XOR b, B = b XOR a XOR b -> B = a //b^=a
A = a XOR b XOR a -> A = b, B = a // a ^= b

En de swap is compleet zonder een extra register om een tempvar in op te slaan :)

[ Voor 23% gewijzigd door Glimi op 19-09-2003 21:27 ]


  • Emmeau
  • Registratie: Mei 2003
  • Niet online

Emmeau

All your UNIX are belong to us

En nog 1

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main(int argc, char* argv[])
{
   int *p;   /* var p */
   int *q;   /* var q */
   int result;  /* result */

   <correct malloc for p en q hier>

   *p=10;  /* zet p */
   *q=2;    /* zet q */

   result = *p/*q;    /* deel de handel */;

   (void)printf ("result =%d\n", result);
}


copieer en compileer
wat is het antwoord dat op het scherm verschijnt?

[ Voor 5% gewijzigd door Emmeau op 19-09-2003 21:51 ]

If you choose to criticise you choose your enemies


Verwijderd

Topicstarter
subtiel ;) maar pas op...straks gaan mensen geen commentaar meer in de code zetten ;)

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Emmeau schreef op 19 September 2003 @ 21:26:
En nog 1
copieer en compileer
wat is het antwoord dat op het scherm verschijnt?
Geweldig subtiel. Ben er met open ogen ingestonken :D
Echter dit is niet iets waar C aan leidt opzich, maar een C-syntax taal ansich heeft. Echter met syntaxhighlighting is de grap er snel vanaf ;)

C:
1
2
3
#include <stdio.h>

int main(int argc, char* argv[] )

Btw fix je main ff naar bovenstaand, dan werkt hij netjes :)

  • windancer
  • Registratie: Maart 2000
  • Laatst online: 18-08 22:36
Het aantal bytes voor een int in niet vastgelegd, de enige eis is dat het minimaal 2 bytes is. Hoeveel het is hangt dus van je compiler af ;)
Exirion schreef op 19 September 2003 @ 21:22:
[...]

Zoiets, maar int is 32-bits dus 2^32-1 :)

  • Exirion
  • Registratie: Februari 2000
  • Laatst online: 04:45

Exirion

Gadgetfetisjist

windancer schreef op 19 september 2003 @ 21:48:
Het aantal bytes voor een int in niet vastgelegd, de enige eis is dat het minimaal 2 bytes is. Hoeveel het is hangt dus van je compiler af ;)
ok ok, maar laten we even uitgaan van 95% van de gevallen bij actuele compilers ;)

"Logica brengt je van A naar B, verbeelding brengt je overal." - Albert Einstein


  • Emmeau
  • Registratie: Mei 2003
  • Niet online

Emmeau

All your UNIX are belong to us

Glimi schreef op 19 september 2003 @ 21:24:
[...]

Wat is daar leuk aan? Het is gewoon een XORswap.
[edit]
A = a, B = b
A = a XOR b, B = b //a^=b
A = a XOR b, B = b XOR a XOR b -> B = a //b^=a
A = a XOR b XOR a -> A = b, B = a // a ^= b

En de swap is compleet zonder een extra register om een tempvar in op te slaan :)
Gcc:

push 1
push 0
call sprintf

(ongeveer, alles wordt volledig weggeoptimaliseerd. Wel is interesant om te zien dat GCC bij een O1 geloof ik, gewoon een register gebruikt om de vars te swappen

Je hebt gelijk dat voor de meeste C-guru's / pro's het niet echt leuk is, maar voor beginners is en blijft het een interessant statement.

Vroeger had je een amerikaans magazine, genaamd Dr. Dobbs, daar adverteerde PCLINT iedere week met een nieuw probleem zoals de /* */ , om aan te geven wat er allemaal aan fouten uit code gehaald kon worden.

[ Voor 24% gewijzigd door Emmeau op 19-09-2003 21:55 ]

If you choose to criticise you choose your enemies


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Emmeau schreef op 19 September 2003 @ 21:53:
Gcc:

push 1
push 0
call sprintf

(ongeveer, alles wordt volledig weggeoptimaliseerd. Wel is interesant om te zien dat GCC bij een O1 geloof ik, gewoon een register gebruikt om de vars te swappen
Ik vind het een vrij stevige optimalisatie ;).
Nou ben ik sowieso altijd vrij voorzichtig met GCC en optimalisaties aangezien sommige niet gegarandeerd goed gaan (zoals -ffull-unroll-loops).
Je hebt gelijk dat voor de meeste C-guru's / pro's het niet echt leuk is, maar voor beginners is en blijft het een interessant statement.

Vroeger had je een amerikaans magazine, genaamd Dr. Dobbs, daar adverteerde PCLINT iedere week met een nieuw probleem zoals de /* */ , om aan te geven wat er allemaal aan fouten uit code gehaald kon worden.
Interessant zeker, maar echt de grap zie ik er niet van in ( mede omdat humor niet echt in het lijstje van mijn karaktereigenschappen staat ). Verder vind ik het wel een zeer interessant topic, dus blijf ermee doorgaan zal ik maar zeggen :)

Vind je het trouwens erg als ik er een '[Alg] Programmeertaal rariteiten' van de titel maak? Dan is het wat breder dan slechts C :)

  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

Gisteravond wilde ik een oud (6 jaar) C/C++ programma van me opnieuw compileren.
Echter dit stukje leverde telkens een syntax error op:
C++:
1
2
3
4
5
6
7
8
void ChangeI (
    int& r,
    int& g,
    int& b,
    int or,
    int og,
    int ob) 
{


line 5: error: syntax error before `||' token

Heeft wel een tijdje geduurd voor het kwartje eindelijk viel :X

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Ook eentje die ik nog wel eens ben tegengekomen:
C++:
1
2
3
4
5
6
int main()
{
    int j = 4;
    cout << j-- << j-- << j-- << j--;
    return 0;
}

De logische output zou zijn 4 3 2 1 maar afhankelijk van je compiler hoeft dat dus niet zo te zijn. VC geeft bijvoorbeeld 1234 in debug mode en 4444 in release mode. De volgorde van evaluatie van subtermen in een expressie is ongedefinieerd, behalve voor de dubbele boolean operators (&& ||) en de sequence operator (,).
Nog eentje:
C++:
1
2
3
4
5
6
7
8
9
int a() { cout << "A"; return 0; }
int b() { cout << "B"; return 1; }
int c() { cout << "C"; return 2; }

int main()
{
    cout << a() << b() << c();
    return 0;
}

Hier wordt de output in VC in zowel debug als release CBA012. De functies worden eerst aangeroepen (in omgekeerde volgorde!) en daarna de resultaten geprint..
Ik denk niet dat je hier vaak mee in de problemen komt maar is toch handig om te weten. Vooral bij de << operator in combinatie met streams kan het wel verraderlijk zijn.

[ Voor 39% gewijzigd door madwizard op 20-09-2003 00:03 ]

www.madwizard.org


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

windancer schreef op 19 september 2003 @ 21:48:
Het aantal bytes voor een int in niet vastgelegd, de enige eis is dat het minimaal 2 bytes is. Hoeveel het is hangt dus van je compiler af ;)

[...]
wat ook niet waar is. Gedefinieerd is dat sizeof (char) <= sizeof (short int) <= sizeof (int) <= sizeof (long int) <= sizeof (long long int)
En dat sizeof (char) = 1

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Dawns_sister schreef op 19 september 2003 @ 23:06:
line 5: error: syntax error before `||' token

Heeft wel een tijdje geduurd voor het kwartje eindelijk viel :X
Nou, bij mij valt het kwartje nog steeds niet :?
code:
1
2
3
4
5
Compiling...
main.cpp
Linking...

CTest.exe - 0 error(s), 0 warning(s)


edit:
okee, nu valt het kwartje wel, blijkbaar staat dat bij VC standaard uit.

[ Voor 11% gewijzigd door Verwijderd op 21-09-2003 15:02 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dawns_sister schreef op 19 September 2003 @ 23:06:
Gisteravond wilde ik een oud (6 jaar) C/C++ programma van me opnieuw compileren.
Echter dit stukje leverde telkens een syntax error op:
C++:
1
2
3
4
5
6
7
8
void ChangeI (
    int& r,
    int& g,
    int& b,
    int or,
    int og,
    int ob) 
{


line 5: error: syntax error before `||' token

Heeft wel een tijdje geduurd voor het kwartje eindelijk viel :X
:?
wat is daar nou fout aan? Ik heb het idee dat ik een bepaalde context mis, maar de code zoals jij 'm hebt (mits er een extra } achter staat) compilet prima

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
.oisyn schreef op 21 September 2003 @ 15:29:
[...]


:?
wat is daar nou fout aan? Ik heb het idee dat ik een bepaalde context mis, maar de code zoals jij 'm hebt (mits er een extra } achter staat) compilet prima
Ik zou nog een goed kijken naar de naamgeving .oisyn. In regel 5 is die wel erg raar, of niet ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Oh, die gare ISO defines. Ik snap niet waarom die ooit zijn ingevoerd

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1