Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Kod koji daje neočekivani rezultat

[es] :: Art of Programming :: Kod koji daje neočekivani rezultat

Strane: << < .. 2 3 4 5 6 7 8 9 10 11 ... Dalje > >>

[ Pregleda: 108685 | Odgovora: 337 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Burgos
Nemanja Borić
Amazon Web Services
Berlin

Član broj: 12484
Poruke: 1947
54.239.6.*

Sajt: stackoverflow.com/users/1..


+480 Profil

icon Re: Kod koji daje neočekivani rezultat27.01.2020. u 14:59 - pre 51 meseci
Izvinjavam se, C ne dozvoljava anonimne unije u ovom obliku. Evo istog programa koji se kompajlira i sa C i sa C++ kompajlerom. Međutim, u C-u je ovaj program potpuno definisan, dok u C++-u ovaj program sadrži undefined behavior (pristupanje neaktivnog člana unije):

Code:
#include <stdint.h>

float InverseSquareRoot(float x)
{
    union unija
    {
        float as_float;
        int32_t as_int;
    };
    union unija u;
    float xhalf = 0.5f*x;
    u.as_float = x;
    u.as_int = 0x5f3759df - (u.as_int>>1);
    u.as_float = u.as_float*(1.5f - xhalf*u.as_float*u.as_float);
    return u.as_float;
}
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat27.01.2020. u 15:37 - pre 51 meseci
Možda je u teoriji u C++ jeziku to nedefinisano, ali u praksi radi. Probao sam sa g++ i clang++ kompajlerom i inverzni kvadratni koren se računa ispravno.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Burgos
Nemanja Borić
Amazon Web Services
Berlin

Član broj: 12484
Poruke: 1947
54.239.6.*

Sajt: stackoverflow.com/users/1..


+480 Profil

icon Re: Kod koji daje neočekivani rezultat27.01.2020. u 15:58 - pre 51 meseci
"U praksi" je vrlo klimav pojam. Ne postoji garancija da će ovaj program raditi na svim implementacijama, pa ni u narednoj iteraciji GNU C++ kompajlera. Već smo videli takve primere sa strict aliasing, sa std::launder, pa se i na ovo ne sme oslanjati.

Howard Hinnant u SO linku sa koga sam preuzeo ovaj primer kaže:

Citat:
This is due to the compiler's choice to compile it like this. It had been equally valid for the compiler to produce different, broken code.


A evo ga i link ka celoj diskusiji unutar C++ komiteta o ovome (WG21 UB study group): http://www.open-std.org/pipermail/ub/2013-July/000071.html
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat27.01.2020. u 16:09 - pre 51 meseci
Imaš li ti primer da to ne radi na nekom kompajleru? Zbog čega bi neko kvario kompajler u sledećim verzijama? Vidi, ako ne postoji fundamentalan razlog protiv toga da radi kako se očekuje, svi će tako da naprave kompajler.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Burgos
Nemanja Borić
Amazon Web Services
Berlin

Član broj: 12484
Poruke: 1947
54.239.6.*

Sajt: stackoverflow.com/users/1..


+480 Profil

icon Re: Kod koji daje neočekivani rezultat27.01.2020. u 16:41 - pre 51 meseci
Imaš li ti dokaz da radi na svakom kompajleru? Pošto standard, koji definiše šta je C++, a ne kompajleri, za ovaj program kaže da je nedefinisan.

Ovaj kod nije portabilan, za razliku od C verzije koja jeste, u kojoj je ponašanje jasno određeno standardom.

Fundamentalni razlog može da bude vrlo prizeman, kao što je optimizacija, kada kompajler može da vidi da se u samo jedno polje unije upisivalo, i da zameni celu uniju samo jednim poljem, ostavljajući sve ostalo nedefinisano.

Već sam ti dao primere u prošlosti kada je kompajler zbog optimizacije kao fundamentalnog razloga, potpuno razbio neportabilne programe. Najčuveniji je strict-aliasing, koji je razbio mnogo toga, uključujući i Linux kernel. Evo Linusova poruka na tu temu (https://lkml.org/lkml/2003/2/26/158, boldovanje moje):


Citat:

Why do you think the kernel uses "-fno-strict-aliasing"?

The gcc people are more interested in trying to find out what can be
allowed by the c99 specs than about making things actually _work_.
The
aliasing code in particular is not even worth enabling, it's just not
possible to sanely tell gcc when some things can alias.


> Some users have complained that when the following code is
>compiled without the -fno-strict-aliasing, the order of the write and
>memcpy is inverted (which mean a bogus len is mem-copied into the
>stream).

The "problem" is that we inline the memcpy(), at which point gcc won't
care about the fact that it can alias, so they'll just re-order
everything and claim it's out own fault. Even though there is no sane
way for us to even tell gcc about it.

I tried to get a sane way a few years ago, and the gcc developers really
didn't care about the real world in this area.
I'd be surprised if that
had changed, judging by the replies I have already seen.

I'm not going to bother to fight it.



https://www.mail-archive.com/[email protected]/msg01647.html

Citat:
That's INSANE. It's so incredibly insane that people who do that should
just be put out of their misery before they can reproduce. But real gcc
developers really thought that it makes sense, because the standard allows
it, and it gives the compiler the maximal freedom - because it can now do
things that are CLEARLY NONSENSICAL.

And to compiler people, being able to do things that are clearly
nonsensical seems to often be seen as a really good thing, because it
means that they no longer have to worry about whether the end result works
or not - they just got permission to do stupid things in the name of
optimization.


So gcc did. I know for a _fact_ that gcc would re-order write accesses
that were clearly to (statically) the same address. Gcc would suddenly
think that

unsigned long a;

a = 5;
*(unsigned short *)&a = 4;

could be re-ordered to set it to 4 first (because clearly they don't alias
- by reading the standard), and then because now the assignment of 'a=5'
was later, the assignment of 4 could be elided entirely! And if somebody
complains that the compiler is insane, the compiler people would say
"nyaah, nyaah, the standards people said we can do this", with absolutely
no introspection to ask whether it made any SENSE.



Još nekoliko primera, kao što su https://davmac.wordpress.com/2009/10/ možeš naći na https://stackoverflow.com/ques...ct-aliasing-and-horror-stories

Ne mogu da pronađem tačno kada je GCC podrazumevano uključio strict aliasing, ali https://www.gnu.org/software/gcc/bugs/ kaže "recently":

Citat:
Recent versions of GCC turn on the option -fstrict-aliasing (which allows alias-based optimizations) by default with -O2. And some architectures then really print "1111 1111" as result. Without optimization the executable will generate the "expected" output "2222 2222".

 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat27.01.2020. u 17:15 - pre 51 meseci
Govorimo o primeru programskog koda koji se kompajlira C kompajlerom, C je portabilan, C++ neportabilan u praksi. Ti ga nisi naveo. Navodiš neke primer koda koji nije C portabilan, što nije tema.

Ja tvrdim da toga nema jer ne postoji razlog za to.

Autore C++ standarda je blam da napišu da se unije koje se kompajliraju C kompajlerom, kompajliraju C++ kompajlerom na isti način, već hoće da formulišu opštu OOP teoriju o uslovima kompajliranja unija, pa to ne uspevaju u celini. Posledica toga je da ono što piše u C++ standardu ne obuhvata sve slučajeve koji su obuhvaćeni C standardom.

Sa druge strane, autori kompajlera itekako razlikuju tipovi koji suštinski nemaju veze sa OOP-om (trivijalni podrazumevani konstruktor, konstruktor kopije, pomerajući konstruktor kopije, destruktor, operator dodele, pomerajući operator dodele, operatori poređenja) zbog optimizacije. Posledica toga je da se svi takvi tipovi koji, koji obuhvataju sve C-ovske tipove (struktura koja ništa ne nasleđuje i nijedna metoda nije navedena je obuhvaćena time) kompajliraju na isti način kao u C-u.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.mediaworksit.net.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat28.01.2020. u 17:58 - pre 51 meseci
Da li neko zna odgovor na pitanje postavljeno ovde

https://www.elitesecurity.org/p3932749
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Burgos
Nemanja Borić
Amazon Web Services
Berlin

Član broj: 12484
Poruke: 1947
54.239.6.*

Sajt: stackoverflow.com/users/1..


+480 Profil

icon Re: Kod koji daje neočekivani rezultat29.01.2020. u 09:01 - pre 51 meseci
Pre nego što operativni sistem da procesu stranice memorije, uvek se izvrši brisanje vrednosti (zapravo, drugačije, neki operativni sistemi to rade na živo pre slanja programu http://lists.dragonflybsd.org/...ommits/2016-August/624202.html, neki uvek dodeljuju 0 stranicu i pomoću CoW daju novu u slučaju da pišeš u nju). U suprotnom, tvoj program bi mogao da dobije stranicu memorije sa šiframa iz Chromiuma, ili slično..

[Ovu poruku je menjao Burgos dana 29.01.2020. u 10:35 GMT+1]

-- EDIT: greške u kucanju.

[Ovu poruku je menjao Burgos dana 29.01.2020. u 10:36 GMT+1]
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.mediaworksit.net.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat29.01.2020. u 10:53 - pre 51 meseci
Da, tako je.

Pre nego što se blok osnlobođen od nekog procesa dodeli nekom drugom procesu, on mora biti popunjennulama iz sigurnosnih razloga.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

chupcko
Negde
Beograd

Član broj: 5560
Poruke: 1141

Sajt: www.google.com


+63 Profil

icon Re: Kod koji daje neočekivani rezultat11.06.2020. u 13:55 - pre 46 meseci

[chupcko@main] 1 /home/chupcko > cat test.java
class test
{
public static void main(String[] args)
{
if(-Integer.MIN_VALUE > 0)
System.out.println("Yes");
else
System.out.println("No");
}
}
[chupcko@main] 0 /home/chupcko > javac test.java
[chupcko@main] 0 /home/chupcko > java test
No


CHUPCKO
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat13.06.2020. u 01:23 - pre 46 meseci
Šta je tu neočekivano? Ako se Integer pamti sa n bitova, onda je najmanji broj min=-2^(n-1), a najveći max=2^(n-1)-1. Naravno da je -min=max+1>max, a pošto se računa po modulu 2^n, od toga se oduzima 2^n i dobija se min kao rezultat. Dakle, -min će biti isto što i min, što je negativno.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
109.72.51.23



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat13.06.2020. u 01:36 - pre 46 meseci
To u Javi gde je definisan overflow i underflow. U C i C++ to je undefined behavior ;)
Dakle da je primer u C-u, rezultat bi bio nepredvidljiv :P
 
Odgovor na temu

chupcko
Negde
Beograd

Član broj: 5560
Poruke: 1141

Sajt: www.google.com


+63 Profil

icon Re: Kod koji daje neočekivani rezultat13.06.2020. u 10:46 - pre 46 meseci
Nedeljko, ti si majstor da promasis temu cak i kada je zicer. Sta mislis sto sam bas u JAVI napisao??? Od 20 jezika koje aktivno koristim, bas JAVA.

Sta je sledece, da mi tvrdis da postoji vrednost v tipa t tako da vazi da je v != v :)
CHUPCKO
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
23.129.64.190



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat13.06.2020. u 12:14 - pre 46 meseci
A sto jes jes rezultat je neocekivan.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat14.06.2020. u 01:24 - pre 46 meseci
Ja ne znam šta kažu članovi Centralnog Komiteta Komunističke Partije standardizacije jezika, znam samo da ne postoji C ili C++ kompajler na kome će ovo da radi drugačije:

Code (c):

#include <stdio.h>
#include <limits.h>

int main(int argc, char **argv)
{
     int x = INT_MIN;
     
     printf("x : %d, -x : %d, -x!=x : %d\n", x, -x, -x!=x);
     
     return 0;
}
 


Naravno, veličina tipa int može da varira, ali će vrednosti za x i -x biti iste i treći ispisani broj će biti 0.

@chupcko

Code (cpp):

class t
{
    bool operator!=(const t&) const { return true; }
};
 

Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
109.72.51.23



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat14.06.2020. u 01:55 - pre 46 meseci
https://www.gnu.org/software/g...ode/Wraparound-Arithmetic.html

Citat:

Signed integer arithmetic has undefined behavior on overflow in C. Although almost all modern computers use two’s complement
signed arithmetic that is well-defined to wrap around, C compilers routinely optimize assuming that signed integer overflow cannot
occur, which means that a C program cannot easily get at the underlying machine arithmetic. For example, on a typical machine
with 32-bit two’s complement int the expression INT_MAX + 1 does not necessarily yield INT_MIN, because the compiler may do
calculations with a 64-bit register, or may generate code that traps on signed integer overflow.

 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat14.06.2020. u 02:10 - pre 46 meseci
Da, vidiš, pravu si.

Cepem ti se u GCC. Sa -O1 -fexpensive-optimizations radi kako treba, a sa -O2 ne radi kako treba. clang radi kako treba i sa -O3.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
109.72.51.23



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat14.06.2020. u 04:45 - pre 46 meseci
a probaj ovo:
Code:

~/.../bmaxa_data/examples >>> cat different.c                                                             
#include <stdio.h>
#include <limits.h>
int f(int x) {
     printf("x-x == %d\n",x-x);
     if (x - x != 0){
         printf("overflow\n");
         return 1;
     }
     return 0;
}
int main(int argc, char **argv)
{
     int x = INT_MIN;
     
     printf("x : %d, -x : %d, -x!=x : %d\n", x, -x, -x!=x);
     f(x); 
     return 0;
}


kod mene:
Code:

~/.../bmaxa_data/examples >>> gcc -O1 different.c                                                                                                                                                                     
~/.../bmaxa_data/examples >>> ./a.out                                                                                                                                                                                 
x : -2147483648, -x : -2147483648, -x!=x : 0
x-x == 0
~/.../bmaxa_data/examples >>> clang -O1 different.c                                                                                                                                                                   
~/.../bmaxa_data/examples >>> ./a.out                                                                                                                                                                                 
x : -2147483648, -x : -2147483648, -x!=x : 0
x-x == 0


ako pogledas kod:
Code:

f:
.LFB11:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $0, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    movl    $0, %eax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc


Kompajleri ni ne gledaju sta je x-x podrazumevaju da je 0.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat14.06.2020. u 07:41 - pre 46 meseci
x-x i jeste 0, bez obzira na to šta je x.

To bi trebalo da bude aritmetika u sistemu ostataka po modulu . Naravno da je .
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

chupcko
Negde
Beograd

Član broj: 5560
Poruke: 1141

Sajt: www.google.com


+63 Profil

icon Re: Kod koji daje neočekivani rezultat14.06.2020. u 09:38 - pre 46 meseci
Ovo nije bas neocekivano, ali ajde ;)


[chupcko@main] 0 /home/chupcko > cat test.java
public class test
{
public static void main(String[] args)
{
if(Float.NaN == Float.NaN)
System.out.println("YES");
else
System.out.println("NO");
}
}
[chupcko@main] 0 /home/chupcko > javac test.java
[chupcko@main] 0 /home/chupcko > java test
NO

CHUPCKO
 
Odgovor na temu

[es] :: Art of Programming :: Kod koji daje neočekivani rezultat

Strane: << < .. 2 3 4 5 6 7 8 9 10 11 ... Dalje > >>

[ Pregleda: 108685 | Odgovora: 337 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.