Praca w C++? czemu programiści nie lubią C++?

0

Wielu twierdzi, że C++ jest trudne do ogarnięcia, ale moim zdaniem C++ jest bardzo podobne do Java i C#. Chyba jedyną trudnością tego języka jest nauczenie się wskaźników i zarządzania pamięcią... więc dlaczego programiści żywią niechęć wobec tego języka?

IDE do C++ są już coraz lepsze.

praca w C++, a praca w webie? ktoś ma doświadczenie na obu polach i podzieli się swoimi doświadczeniami? jakie są specyficzne różnice?

6

Chyba jedyną trudnością tego języka jest nauczenie się wskaźników i zarządzania pamięcią

Nauczenie się wskaźników to względnie prosta sprawa, ale bolesne jest kopanie się z losowymi segfaultami i dziwacznym zachowaniem programu, gdy pomylisz się w obsłudze wskaźników. Po co tracić życie na coś takiego zamiast implementować jakiś fajny ficzer? Nie każdy odczuwa przyjemność z obcowania ze wskaźnikami.

0

C++ nie jest trudne do ogarnięcia, ale po prostu tracisz dużo więcej czasu na rzeczy, które w innych językach zrobisz szybciej i prawdopodobnie lepiej, bo ktoś bardziej doświadczony dał Ci "podstawę".

7

Chyba jedyną trudnością tego języka jest nauczenie się wskaźników i zarządzania pamięcią...

Mało jeszcze wiesz... :P

1
Złoty Pomidor napisał(a):

Wielu twierdzi, że C++ jest trudne do ogarnięcia, ale moim zdaniem C++ jest bardzo podobne do Java i C#. Chyba jedyną trudnością tego języka jest nauczenie się wskaźników i zarządzania pamięcią... więc dlaczego programiści żywią niechęć wobec tego języka?

Po 8 latach w cpp przesiadek się na c#
Już nie muszę martwić się reference collapising
Kiedy jest Universal ref a kiedy r value

Itp itd

Żeby zarabiać w cpp tyle co w c#, js, java trzeba parę razy więcej wiedzieć

A jak się nie musi to po jakiego grzyba się męczyć

0

Bo większość ludzi zna starego C++ z musem pisania wskaźników, new i innych dziwactw. Kontenery, smart pointery, auto, czy inicjalizacja klamrowa wiele ułatwiają ;)

0

Bo większość ludzi zna starego C++ z musem pisania wskaźników, new i innych dziwactw. Kontenery, smart pointery, auto, czy inicjalizacja klamrowa wiele ułatwiają ;)

Tyle, że jak nawstawiasz wszelkie bajery (sprytne wskaźniki, metody wirtualne, sprawdzanie indeksów tablic, sprawdzanie nullptr przy każdym korzystaniu z wskaźników itp itd) zbliżające C++ np do Javy to zostaniesz z czymś wolniejszym od Javy, więc jaki w tym sens? Sprytne wskaźniki są natomiast ułomne (i to każdy rodzaj sprytnych wskaźników) z bardzo prostego powodu - nie radzą sobie z cyklicznymi referencjami i nie nadają się do współdzielenia stanu (obojętne czy mutowalnego czy nie) między wątkami (bo albo są oparte o kosztowne operacje atomowe albo psują się przy korzystaniu z wielu wątków jednocześnie). Odśmiecanie pamięci (w sensie tracing GC) jest znacznie wygodniejsze i kompletne.

0

A to w języku trzeba pisać tylko dlatego, że jest szybszy niż inny? Gdyby tak było nie wychodziłbym poza C. :)

Ponadto, prosiłbym o jakieś dane potwierdzające tezę o tym, że smart pointery czy .at() przy std::array spowalnia program, bo mam inne informacje. 

1

Z Javy korzysta się zamiast z C w aplikacjach biznesowych bo łatwo ją przenieść (JVM ) i kod jest czytelniejszy.C++ z typi pierdołami typu smart pointery itd. jest mniej czytelny od Javy i wolniejszy od niej (wedlug tego co napisał @Wibowit). Ma więc wady C i wady Javy, zalet nie widze

3

Ponadto, prosiłbym o jakieś dane potwierdzające tezę o tym, że smart pointery czy .at() przy std::array spowalnia program, bo mam inne informacje.

W prostych benchmarkach różnic pewnie dużych nie będzie, bo proste przypadki się prosto optymalizuje. Trzeba by było wziąć jakiś większy algorytm i dorobić wszędzie te rzeczy o których pisałem (sprytne wskaźniki, sprawdzanie nullptr przy każdym wykorzystaniu wskaźnika, sprawdzanie indeksów tablic, itp itd). Zrobiłem jednak prosty benchmark symulujący pointer chasing:

#include <array>
#include <vector>
#include <cstdlib>
#include <chrono>  // for high_resolution_clock
#include <inttypes.h>

int main(int argc, char** argv) {
    std::array<int32_t, 100> tablica;
    for (int32_t i = 0; i < 100; i++) {
        tablica[i] = (i * 34373 + 43) % 100;
    }
    int64_t iterations = 1000000000;

    int64_t op_sum = 0;
    int64_t op_index = 0;
    auto op_start = std::chrono::high_resolution_clock::now();
    for (int64_t i = 0; i < iterations; i++) {
        op_sum += tablica[tablica[tablica[tablica[op_index]]]];
        op_index = i % 100;
    }
    auto op_finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> op_elapsed = op_finish - op_start;

    int64_t at_sum = 0;
    int64_t at_index = 0;
    auto at_start = std::chrono::high_resolution_clock::now();
    for (int64_t i = 0; i < iterations; i++) {
        at_sum += tablica.at(tablica.at(tablica.at(tablica.at(at_index))));
        at_index = i % 100;
    }
    auto at_finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> at_elapsed = at_finish - at_start;

    printf("%" PRId64 ", %lf\n", op_sum, op_elapsed.count());
    printf("%" PRId64 ", %lf\n", at_sum, at_elapsed.count());
    return EXIT_SUCCESS;
}

Wyniki:

49500000041, 1.517305
49500000041, 1.774159

To jest nadal bardzo prosty kod i niespecjalnie wykorzystuje możliwości procesora w zakresie (spekulatywnego) wykonywania kodu poza kolejnością. Na jakimś słabym procku pewnie różnice byłyby znacznie większe.

Sprawdzanie indeksów tablic czy nullptrów można zoptymalizować zarówno podczas kompilacji AOT jak i JIT. Zarówno kompilatory C++ jak i JVM to robią i dla prostych benchmarków nie ma dużej różnicy wydajnościowej między C++, a Javą. Gdy optymalizatory wysiadają zwiększa się spadek wydajności spowodowany tymi bajerami typu sprawdzanie indeksów tablic czy nullptrów.

Poza tym, gdyby sprawdzanie indeksów tablic i nullptrów było całkowicie darmowe w C++ to wtedy zupełnym nieporozumieniem byłoby utrudnianie korzystania z tego. Korzystanie z operatora [] jest wygodniejsze niż z metody .at, więc ludzie korzystają z [] narażając się na irytujące problemy czy wręcz niebezpieczeństwa. Sprytne wskaźniki to ceremonia w porównaniu np do jednego rodzaju referencji jak to jest w większości popularnych języków (Java, C#, JS, PHP, Python, etc). Sam kompilator C++ nie wymusza też reguł stosowania sprytnych wskaźników. Robi to natomiast kompilator Rusta, więc Rust ma tutaj przewagę nad C++em (jedną z wielu).

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0