• 6 758 online
  • 1 153 490 medlemmar
  • 59 668 845 inlägg
2018-02-15, 11:27
  #121
Medlem
RostigHinks avatar
Även gcc varnar om man har -Wall på. gcc tycker att resultatet ska vara 5.
Citera
2018-02-16, 02:55
  #122
Avstängd
.profiles avatar
Citat:
Ursprungligen postat av Nightling
result += ++val1 * val2 + (double)((val2 * val3 + val4) % val3 /val1);

Trots att operationerna +, *, &, ^ och | inte är helt kommutativa och associativa i C, p.g.a. signade tal, möjligheten för over-/underflow, tappad precision i flyttal, och sidoeffekter, får kompilatorn ändå utnyttja att de är det matematiskt och byta ordning på operanderna och/eller flytta parenteserna. T.ex. kan `(a + b) + c` beräknas som `(c + a) + b`. Det gäller bara när man använder samma operator flera gånger i rad - inte kombinerat som med distributivitet, och en subtraktion är alltid en subtraktion, inte en addition av det negativa talet.

Om a, b och/eller c är funktionsansrop (eller volatila minnesplatser) kan de anropas (accessas) i vilken ordning som helst. Om b var ett negativt tal som skulle förhindra overflow inför additionen med c, kan man ha skitit i det blå skåpet. Om a, b och c är extrema flyttal, kan evalutionsordningen vara skillnaden mellan liv och död.

Dela upp beräkningen i två statements.

EDIT: Då du konverterar en av additionens två operander, tror jag att kompilatorn inte får byta ordning på dem. Där drog man tydligen gränsen... Och eftersom du inte modifierar någon variabel mer än en gång mellan sequence points, tror jag att resultatet faktiskt är definierat.
__________________
Senast redigerad av .profile 2018-02-16 kl. 03:31.
Citera
2018-02-16, 14:50
  #123
Medlem
kaks avatar
Citat:
Ursprungligen postat av .profile

EDIT: Då du konverterar en av additionens två operander, tror jag att kompilatorn inte får byta ordning på dem. Där drog man tydligen gränsen... Och eftersom du inte modifierar någon variabel mer än en gång mellan sequence points, tror jag att resultatet faktiskt är definierat.
Om man modifierar ett värde mellan två sekvenspunkter får man inte läsa det med annat syfte än att undersöka värdet som skrivs. Därmed är koden inte korrekt.
Citera
2018-02-18, 18:10
  #124
Medlem
Citat:
Ursprungligen postat av .profile
Trots att operationerna +, *, &, ^ och | inte är helt kommutativa och associativa i C, p.g.a. signade tal, möjligheten för over-/underflow, tappad precision i flyttal, och sidoeffekter, får kompilatorn ändå utnyttja att de är det matematiskt och byta ordning på operanderna och/eller flytta parenteserna. T.ex. kan `(a + b) + c` beräknas som `(c + a) + b`. Det gäller bara när man använder samma operator flera gånger i rad - inte kombinerat som med distributivitet, och en subtraktion är alltid en subtraktion, inte en addition av det negativa talet.

Om a, b och/eller c är funktionsansrop (eller volatila minnesplatser) kan de anropas (accessas) i vilken ordning som helst. Om b var ett negativt tal som skulle förhindra overflow inför additionen med c, kan man ha skitit i det blå skåpet. Om a, b och c är extrema flyttal, kan evalutionsordningen vara skillnaden mellan liv och död.

Dela upp beräkningen i två statements.

EDIT: Då du konverterar en av additionens två operander, tror jag att kompilatorn inte får byta ordning på dem. Där drog man tydligen gränsen... Och eftersom du inte modifierar någon variabel mer än en gång mellan sequence points, tror jag att resultatet faktiskt är definierat.
I det generella fallet får kompilatorn inte flytta parenteser då det påverkar resultatet. I fallet med flyttal så påverkas avrundningsfelet om operanderna adderas i annan ordning. Dock gäller generellt att kompilatorn är fri att göra vilka optimeringar den vill som inte påverkar resultatet av ett välformulerat program, så adderar man t.ex. heltal så kan kompilatorn flytta parenteserna därför att den kan se att resultatet inte påverkas.

Den aktuella drabbas däremot av att evalueringsordningen av funktionsargument av historiska skäl är odefinierad i C.
Kod:
z = f(g(x), h(y));
I fallet ovan måste g(x) och h(y) exekveras innan f() kan anropas och ordningen detta görs är odefinierad. Operatorer är syntaktiskt socker för funktionsanrop och således är resultatet av följande kod också odefinierat:
Kod:
int x = 1;
int y = ++x + x;
Citera
2018-02-22, 17:00
  #125
Medlem
Citat:
Ursprungligen postat av Herz
Tack för era svar.

Har bestämt mig för att lära mig C# först och sen titta in lite mer på C++.

Känner ni till någon bra bok som ger en bra introduktion till C#?

Har ni annars några tips på alternativt material på internet?
Om du är intresserad av hårdvarunära programering är nog C/C++ eller assembler de mest lämpade språken. VHDL utför man i egentlig mening inte programering med, utan ett språk för att konstruera elektriska kretsar i en FPGA exempelvis. Kan vara bra om du har behov för att utföra operationer parallellt exempelvis.

Med C# kan du alltid skapa ett webbaserat system via exempelvis visual studio och MVC (model control view). Då är det passande att skapa en databas så kan du alltid lära dig sql/linq samtidigt osv. Kanske kan vara ett bra första projekt.
Citera