- Yettel topik
- Milyen okostelefont vegyek?
- iPhone topik
- Apple iPhone 16 Pro - rutinvizsga
- További kavarás a Pixel 10-ek körül
- Xiaomi 13T és 13T Pro - nincs tétlenkedés
- Okosóra és okoskiegészítő topik
- Samsung Galaxy S25 Ultra - titán keret, acélos teljesítmény
- Egyszerre legnagyobb és legkisebb is a Garmin Venu X1
- Magyarországon is kapható a Moto G85 5G
Új hozzászólás Aktív témák
-
-
ToMmY_hun
senior tag
Jól összefoglaltad a lényeget. Nekem az a tapaszlatom (igaz nem C++ tekintetében) hogy sokszor a program logikája is hibás, redundáns kódrészeket, felesleges műveleteket tartalmaz. Egyik nap egy éles kódban láttam egy ilyet: if(a != b) a = b; Nyilván ez nem olyan nagy overhead, de ha kicsiben ilyen hiba van, akkor nem szeretném tudni hogy mi van magasabb szinteken. Ezek sokkal komolyabb programozási/tervezési hibák, mint egy pre/post increment felcserélés és nagyobb a miatta keletkező overhead is. A kód futási ideje nem olyan kritikus, de minek kell nyüstölni a hardvert ha egy kicsi gondolkodás árán lehet kímélni is? Kár, hogy egyetemeken nem fordítanak kellő figyelmet arra, hogy hatékony, könnyen érthető de mellette robosztus kódot írjanak a diákok. Mi villmérnökök mikrokontrolleren kezdtük el programozni, ráadásul 8 bites csodákon. Szerintem azok rettenetesen jók arra, hogy lássa és tapasztalja az ember azt, hogy miért fontos optimális kódot írni.
-
jattila48
aktív tag
Ok, ebben nem értünk egyet. Nyilván elsősorban a programom logikájára figyelek, de tőlem abszolút nem igényel semmiféle "görcsölést", hogy alapból a pre op-ot használjam. Persze mások vagyunk, lehet hogy neked ez fölöslegesen elvonja a figyelmed az alkotástól. Mindenesetre szerintem általában javasolható a pre op használata.
Egyébként viszonylag ritkán van szükség kifejezetten a post op alkalmazására. Én leginkább konténer kiürítésénél használtam. -
dobragab
addikt
Ezért van rossz híre a nyelvnek - valójában non-issue az összes ilyen; ha nem akarsz vele foglalkozni, nem kell, semmi nem kötelező.
+1
C++-ban szerintem nincsenek ökölszabályok, max. jól bevált módszerek. Pl. a 3-5-ös szabály sincs kőbe vésve: gondolj csak egy rejtett proxy objektumra, pl. az std::vector<bool> indexelő operátorának visszatérési értékére. op= tuti kell, hogy jól menjen az egymásnak értékadás, míg dtor-ra tuti nincs szükség.
-
jattila48
aktív tag
Én csak azt nem értem, hogy szerinted miért olyan nagy fáradság figyelni rá, mi nem ér annyit? Mennyit? Ha tudod, hogy a pre verziót is lehetne használni, akkor "véletlenül" nem fogod a post-ot. Vagy annyira erős koncentrációt igényel tőled, hogy erre figyelj, ezért random hol ezt, hol azt használod? Ha meg tudod, hogy elvileg mindegy melyiket használod, akkor "csak azért is" néha a post-ot?
"Ha code review-n megjelenik okoska, hogy hé, véletlenül másikat használtad, 5 billentyű leütés kijavítani."
Ha kijavítani csak ennyi, akkor "jól" írni még ennyi sem. -
jattila48
aktív tag
"Így most azt mondod, hogy a fordító egy függvényhívást lecserélhet egy másik függvény hívására, ha bizonyos feltételek teljesülnek"
Végül is igen. Persze csak akkor, ha post verzió a "szokásos módon" mellékhatások nélkül van megvalósítva.
"Ha másik fordítási egységben van definiálva, akkor teljesen más dolgot csinálhat a kettő, és erről a fordító SEMMIT nem tud."
Hát ez valóban probléma! Igazából úgy lehetne ezt elképzelni, ha megadható lenne, hogy a fordító automatikusan generáljon post verziót a pre verzióból. Ilyen persze tényleg nincs.
-
jattila48
aktív tag
Az általam írt optimalizáció megvalósításában valószínűleg annak eldöntése lehet a legnehezebb (esetleg lehetetlen), hogy van-e a post verziónak mellékhatása. A szokásos megvalósításban ez a mellékhatás csak a copy ctor-ban lehet. Elképzelhető, hogy a szabvány nem engedi meg a mellékhatás kioptimalizálását (ellentétben az RVO-val, ahol a copy ctor mellékhatását engedi figyelmen kívül hagyni). Ez esetben tényleg nem ez a járható út. Ha viszont a post verziónak van mellékhatása, akkor a programozónak főleg foglalkoznia kell azzal, hogy melyiket használja.
-
jattila48
aktív tag
Ha már a Google-nál dolgozol, nyilván ismered:
Google C++ Style Guide
Preincrement and Predecrement
Use prefix form (++i) of the increment and decrement operators with iterators and other template objects.
When a variable is incremented (++i or i++) or decremented (--i or i--) and the value of the expression is not used, one must decide whether to preincrement (decrement) or postincrement (decrement).
When the return value is ignored, the "pre" form (++i) is never less efficient than the "post" form (i++), and is often more efficient. This is because post-increment (or decrement) requires a copy of i to be made, which is the value of the expression. If i is an iterator or other non-scalar type, copying i could be expensive. Since the two types of increment behave the same when the value is ignored, why not just always pre-increment?
The tradition developed, in C, of using post-increment when the expression value is not used, especially in for loops. Some find post-increment easier to read, since the "subject" (i) precedes the "verb" (++), just like in English.
For simple scalar (non-object) values there is no reason to prefer one form and we allow either. For iterators and other template types, use pre-increment.
Úgy látszik, hogy a céged mégiscsak elvárja, hogy foglalkozz ezzel.
-
jattila48
aktív tag
Nem feltétlenül iterátorra gondoltam. Más bonyolultabb objektumnak is lehet inkrementáló operátora, amit esetleg tényleg nem lehet inline-olni (más kérdés, hogy van-e értelme). Az RVO-t csak arra írtam, hogy ha azt a fordító (és nem külön menetben az optimalizáló) végzi, akkor akár ezt is elvégezheti, amit írtam, Egyáltalán nem biztos hogy megcsinálja, de számomra ez még egyszerűbb feladatnak tűnik mint az RVO. Persze az igaz, hogy csak akkor, ha a ctor, dtor-nak nincs mellékhatása.
"Ahhoz, hogy úgy működjön a fordító, hogy detektálja, hogy most ki lehet cserélni a pre-t post-ra, úgy, hogy minden esetben működjön, ahogy te leírod, nagyon okosnak kell lennie"
Ahol nem használja a post visszatérő értékét ott kicseréli, máshol meg nem. Vagy ez nem ilyen egyszerű?
Akárhogy is van, azzal hogy "akkor ne foglalkozz vele, mert nem ér annyit", nem értek egyet. Szerintem ez nem különösebben teszi próbára a programozót, hogy adott esetben el tudja dönteni, tényleg szüksége van-e a post verzióra, vagy elég a pre is. Vagyis igenis foglalkozzon vele , mert megér annyit. Szerintem ezt hogy a post lassabb lehet, illik tudni egy programozónak. Kód review-ban én szóvá tenném, míg azt a valóban szerencsétlen bool értékadást nem.
Más, nem csak neked címezve:
Makrók és template metaprogramming használatával olyan programot szeretnék írni, amit újra fordítva, az előzőleg fordítottal funkcionálisan megegyező, azonban bináris kódjában erősen különböző kódot kapok. Ez egy kicsit bonyolult mondat lett, tehát a lényeg: makrókkal és TMP-vel bináris kód obfuszkáció. Hatékonyság nem lényeg, lehet bele (sőt...) redundáns kódot injektálni, hadd legyen minél nehezebben követhető a kód. Olyanokra gondoltam mint értékadás, függvényhívás, bool kifejezések bonyolítása, loop unrolling, stb. Ha van ezzel kapcsolatban ötletetek, ne tartsátok magatokban. Ja, és ne akarjatok lebeszélni róla, hogy ugyan minek ez nekem. Köszi előre is.
-
ToMmY_hun
senior tag
Ha publikus akkor megosztanád hogy milyen területen programozol? Érdekelne hogy mi az, ahol ennyire ügyelni kell az optimális kódra.
Persze, elméletileg mindenhol, de nem mindenhol van idő/lehetőség a kód optimalizálására és én örülnék neki ha csak ilyen overheadek lennének a kódokban amiket nap-mint-nap látok.
-
jattila48
aktív tag
Ez még csak OK lenne, ha inlineolható az operátor és a copy ctor. De mi van, ha fv. hívásokként kell befordítani? Akkor ez már nem működik. Viszont az könnyen eldönthető, hogy valójában nincs is szükség a post inkrement verzióra, ezért egyszerűen a pre verziót fordítja be. Ez is egyfajta optimalizáció. Természetesen, ha post verziónak mellékhatása van (akár a copy ctor miatt), akkor a fordító úgy ítéli meg, hogy igenis szükség van rá, ezért valóban a post verziót fordítja be. Ez akkor is működik, ha a post verzió nem inlineolható, míg amit te írtál, az kénytelen lesz az egyébként szükségtelen post verziót használni, ha máshol pedig okkal használják a post verziót. Nem tudom, hogy így vagy úgy van-e, ki kéne próbálni. Valahogy biztos meg lehet tiltani az inline-olást, abból kiderülne. Azt írod, hogy a "generált kódra rámozdul az optimalizáló", ami egész biztos, hogy jórészt így is van. Azonban pl. pont az RVO-nál gondolom már a fordító generál optimalizált (akár köztes) kódot, amivel a köztes kódon operáló optimalizációnak már nem lesz dolga (legalábbis nem az RVO tekintetében). Most úgy gondolom (nem biztos hogy így van), hogy az RVO-t nem is lehet másként, mint elve a fordítóra bízni (nem pedig a külön menetes optimalizálóra), akkor pedig miért ne végezhetné el az általam írt optimalizációt is maga a fordító?
-
jattila48
aktív tag
De hát pont arról volt szó, hogy nem változtatja meg ezzel program működését, hiszen nem használja az operátor visszatérő értékét, így nyugodtan használható a pre inkrement verzió. Igen csodálkoznék, ha úgy lenne, ahogy írod, mert akkor más fordítási modulban, ahol szükségszerű a post inkrement verzió ott mit csinál? A kód optimalizálók általában nem globálisan, hanem csak fordítási egységenként működnek. Vagy ha másik modulban post inkrement kell, akkor oda is azt fordít, ahova nem kéne, de azt használják? Ez számomra nagyon nem tűnik logikusnak, és jóval egyszerűbb így megvalósítani, ahogy írtam. Némileg magadnak is ellent mondasz ("annyira nem eszik forrón a kását"), mert ha így lenne ahogy írod, akkor igenis figyelni kellene, hogy tényleg csak a szükséges helyeken használjuk a post inkrement verziót ("Szóval
nemérdemes ebbe energiát befektetni").
BTW elárulnád, hogy mi a baj azzal, ha a post inkrement op-ot pre inkrementtel valósítom meg? -
jattila48
aktív tag
"Ha nem használod a visszatérési értéket (mint pl. a for ciklusban), akkor erősen valószínű, hogy optimalizálás után pontosan ugyanazt a kódot generálja akkor is, ha saját operátorokat definiálsz"
Úgy tűnik, hogy ilyenkor egyszerűen a pre inkrement verziót fordítja be akkor is, ha post inkrementet használsz. Ettől persze még igaz, hogy maga a post inkrement verzió kb. egy copy ctor-ral költségesebb.
-
jattila48
aktív tag
Elképzelhető, hogy így van. Természetesen mindig a logikának megfelelőt kell használni, de magam részéről ha logikailag mindegy, mindig a pre inkrement verziót használom. Nem POD-ra gondoltam, ezt rosszul írtam, hanem csak az alaptípusokra. Ha nincs optimalizálás, akkor szerintem kb. úgy van, ahogy írtam. Legalábbis én így írtam post inkrement operátort, de valószínűleg nem is lehet ettől nagyon különböző módon.
-
jattila48
aktív tag
Na, erre mondom, hogy "túldizájnolás". A tomb maris egy konténer, aminek van iterátora. Az iterátorokat át kell adni a find függvénynek. Mit csinálsz, ha a tomb-ben a következő megfelelő elemet is meg kell találnod (elem=find(++elem, end(tomb), feltetel))? A példát arra írtam, hogy vannak olyan egyszerű esetek, amiket egyszerűen kell megoldani, és akkor nyugodtan használható a break. Ha egy sima karaktertömbben kell elvégezni ezt a feladatot, akkor a konténerek, iterátorok, és standard függvények használata, biztos, hogy lassabb (még inlineolva is) és nagyobb kódot eredményez.
-
dobragab
addikt
Onnan, hogy pár hsz-szel feljebb olyat kérdezett, ami kezdőre vall.
Persze lehet, hogy tévedek. Ha viszont kezdő, akkor az std::begin() meg std::end() és társai nem hiszem, hogy segítenék az algoritmus megértését.
-
ToMmY_hun
senior tag
Igen, ügyes voltam és különbözővel próbálkoztam.
Ma is tanultam valamit. 2015-höz való Qt sajna nincs, elvileg jövő héten jön az 5.6 RC, utána valamikor (talán) lesz fordított is. Nekem sürgős, szóval fordítanom kell egyet a 2015-tel és akkor örülünk. MinGW-vel nem szórakozok, windowson elég béna szegény.
-
ToMmY_hun
senior tag
Az error direktíva működött, szóval a headert látja. Maga a header így néz ki:
#pragma once
#include "Logger.h"
#include <iostream>
#include "ArmCreator.h"
#include "Calculation.h"
#include <chrono>
#include <thread>
#include "Communication.h"
#include "Simulation.h"
namespace RoboticArm {
class ArmRunner
{
private:
// Singleton behavior member variables
static bool instanceFlag;
static ArmRunner* single;
ArmRunner();
~ArmRunner();
// Normal member variables
Calculation* calc = Calculation::getInstance();
Matrix effectorPosition;
ArmCreator* AC = ArmCreator::getInstance();
public:
// Singleton behaviour
static ArmRunner* getInstance();
Logger* log = Logger::getInstance();
// Normal methods
void initialize();
void operate();
};
}Ez pedig a használat Qt-ben:
#include "mainwindow.h"
#include <QApplication>
#include "include/ArmRunner.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
// Ezt a harom sort adtam a projekthez:
RoboticArm::ArmRunner* arm = RoboticArm::ArmRunner::getInstance();
arm->initialize();
arm->operate();
return a.exec();
}Feltoltam dropboxra a projektet, hátha valakinek lenne ingerenciája megnézni.
-
ToMmY_hun
senior tag
Header include meg volt, a függvény pedig a static lib-ben van definiálva. Headerben függvény deklarációk vannak, ahogy az a nagykönyvben meg van írva. Azt is értem hogy nem találja a függvény definíciót, de pont azt kellene a lib-ből kiolvasnia, nemde?
UI: Visual Studioban hibátlanul megy a lib, használom is egy ideje.
-
jattila48
aktív tag
Ez alapján valóban így lehet, ahogy írod. Én a Visual Studio 2012-őt használom, és még debug módban sem hívja a copy ctort T s=T() -re. Ellenben a my_matrix-ot érték szerint visszaadó operátoroknál debug módban nincs RVO (meghívódik a copy ctor), release módban pedig van RVO, annak ellenére, hogy a copy ctor-ban logolás van. Mondjuk azt nem értem, hogy a T x=t (ahol t temporális (és T típusú, bár talán ez sem fontos)) inicializálásnál mégis miért hívnák meg a copy ctort? Egyáltalán van ilyen fordító? A T s{} inicializálást a VS2012 nem ismeri, ezért nem azt használtam.
-
jattila48
aktív tag
T s=T(); nem hívja az értékadó operátort, ez mindössze egy default ctor hívás. Ennek nincs köze a copy elision-höz és egyéb optimalizációhoz sem, debug módban is csak ennyi. Amit írtál az le sem fordul, lokális fv.-ként próbálja értelmezni. Egyébként a T s; pedig az alaptípusok miatt nem elegendő (pl. int), mert deklarálja az s-t, csak éppen nem inicializálja 0-val. Szóval szerintem jó ez így. Egyéb "hiba"?
-
EQMontoya
veterán
Én azért alapvetően igyekszem távol tartani magam tőle.
Persze, van, amikor kényelmesebb és tényleg van, de láttam már referenciát váró függvényt pointerrel meghívva lefordulni és lefutni az elb..ott konverziós konstruktorok miatt. Szóval amit nem használunk feltétlenül, az legyen explicit, és alap típusok esetén mindenképp. -
EQMontoya
veterán
-
EQMontoya
veterán
Ha az operátor paramétere ugyanolyan típus (vagy - mint jelen esetben - hasonló típus, ami valamelyik template paraméterében eltér), akkor mindegy, mert így is - úgy is jó lesz.
Abban igazad van, hogy teljesen más típus esetén (pl. konstanssal szorzás) nyilván nem célszerű.
Én azért azt vallom, hogy amit nem feltétlen kell frienddel megcsinálni, azt ne csináljuk. -
Zsolt1
tag
Köszi a segítséget neked is és EQMontoyanak is, a dinamikus tömböt csak azért raktam bele, mert gyakorlaton is ez volt és nem volt erre vonatkozó instrukció, hogy kell-e vagy nem, de közben mástól is megkaptam javaslatban, hogy inkább nem kéne
.
A kommentezésen gondolkoztam hogy kiszedem, mert tényleg zavaró lehet, de valahogy nem volt már erőm egyesével törölgetni, mert komment + "dokumentációval" (pár sor txt-be) kell majd leadnom és inkább írtam párhuzamosan, most viszont kiszedtem(egyébként pte).
Megcsináltam azokat, amiket mondtatok(legalábbis remélem, hogy pontosan azokat), viszont még mindig lefagy valamiért futás után és nem is adja hozzá a sort (ugyan azt a tömböt kapom vissza a művelet után). A codeblocks most nem dob semmilyen hibaüzenetet fordítás alatt. Kiírattam futás közben és elvileg megcsinálja a másolást ott ahol kell, a 4 sorban viszont kiíratáskor ez már nem látszik. main.cpp Matrix.h Matrix.cpp
Új hozzászólás Aktív témák
Hirdetés
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- bambano: Bambanő háza tája
- sziku69: Fűzzük össze a szavakat :)
- AMD Ryzen 9 / 7 / 5 9***(X) "Zen 5" (AM5)
- One otthoni szolgáltatások (TV, internet, telefon)
- Sony MILC fényképezőgépcsalád
- Yettel topik
- Szünetmentes tápegységek (UPS)
- Milyen videókártyát?
- Motorolaj, hajtóműolaj, hűtőfolyadék, adalékok és szűrők topikja
- Okos Otthon / Smart Home
- További aktív témák...
- MSI Sword 15 A12VF 15.6" FHD IPS i7-12650H RTX 4060 16GB 512GB NVMe gar
- GAMER PC : RYZEN 7 7800X3D /// 32 GB DDR5/// RX 9070 XT 16GB /// 1TB NVME
- Eladó garanciális Hohem iSteady V2S gimbal
- Creative 3D Blaster 3Dfx Voodoo Banshee PCI (CT6760)
- Samsung Galaxy S22 Ultra 12/256GB Megkímélt,Kétkártyás,Tartozékaival. 1 év Garanciával!
- Intel Core 2 Quad Q9550 2.83GHz LGA775 Processzor
- BESZÁMÍTÁS! Gigabyte B760M i5 14600KF 64GB DDR4 512GB SSD RTX 3080 10GB Corsair 4000D Airflow 1000W
- BESZÁMÍTÁS! Gigabyte Z370M i5 9400F 16GB DDR4 512GB SSD RX 5700XT 8GB ZALMAN S2 TG Corsair S650W
- Alkatrészt cserélnél vagy bővítenél? Nálunk van, ami kell! Enterprise alkatrészek ITT
- Telefon felvásárlás!! iPhone 12 Mini/iPhone 12/iPhone 12 Pro/iPhone 12 Pro Max
Állásajánlatok
Cég: PC Trade Systems Kft.
Város: Szeged
Cég: CAMERA-PRO Hungary Kft
Város: Budapest