LINUX.ORG.RU

Поломана совместимость с С в С++11?

 


2

2
cat test.cpp 
#include <stdio.h>

int main(int argc, char** argv)
{
	auto int i = 2;
	printf("Hello!\n");
	return 0;
}
 gcc test.cpp.
/a.out
Hello!
 g++ test.cpp
 ./a.out 
Hello!
 g++ --std=c++11 test.cpp 
test.cpp: В функции «int main(int, char**)»:
test.cpp:5:11: ошибка: два или более типа в декларации имени «i»

Ваши мнения по этому поводу.

Ответ на: комментарий от tailgunner

Давай sloccount.

Их не так просто сравнить - в составе gcc полно библиотек, которых нет в LLVM (или которые там не нужны). Да и всякие testsuite повыкидывать надо из них. Мне лениво.

P.S. называть llvm и clang «простыми, как грабли» - дешевые понты.

Чего? LLVM и Clang просты, как грабли, глупо с этим утверждением спорить. Единственное сложное место вообще в LLVM - это InstCombine pass, и как раз он-то написан в лучшем сишном стиле, задней левой пяткой по пьяни, с полным презрением к идеалам ООП. Все остальное - это такие маленькие, тупые, примитивные кубики, каждый из которых очень легко понять по отдельности.

anonymous
()

C никогда ни с чем не был совместим с C++, особенно в плане классов и пространства имен, хотя и в этом что-то есть ) Не стоит так-же забывать, что стандартная библиотека C++ включает в себя библиотеку C (cstdio.h) и т.д так-что можно считать, что C++ полностью включает в себя C.

Sharezil
()
Ответ на: комментарий от anonymous

Для типа комплексных чисел(или там еще каких) не нужны препроцессоры и генераторы кода.

Не нравятся комплексные - возьмите бигнумы. И да, речь о программистах, пишущих на Си руками. Как выходной код С почти идеален, да.

anonymous
()
Ответ на: комментарий от anonymous

Пусть задачу выбирают чистосишники - так не будет повода отмазаться.

Ваши примеры не имеют отношения к делу. Большая часть относится ко временам старого(еще даже до 1998/2003стандарта) С++.

Сейчас на С++ пишут. И новые СУБД(MySQL, MongoDB и пр.), и ОС(Windows из известных, много непопулярных), и компиляторы(clang) и llvm'ы всякие.

firefox написан через одно место. Сишники, наверно, писали.

И еще раз - подсчет ссылок не является фичей языка С++.

anonymous
()
Ответ на: комментарий от anonymous

move-семантика же теперь есть - не надо костыли писать.

anonymous
()
Ответ на: комментарий от Dron

Вот скажи мне что будет если я пишу приложение с двумя потоками и один берёт переменную и в цикле её умножает, другой поток тоже в цикле и её читает и при её изменении тоже производит расчёты с ней используя её как множитель? Что будет если я явно не укажу переменной в первом потоке volatile и положусь на компилятор?

В твоем случае всегда будет фейл, так как нужно использовать синхронизацию. Это во-первых, во-вторых, переменная не может быть отправлена в регистр, если ее может читать другой поток - т.е. если эта глобальная переменная или член класса. Локальные переменные в функциях или аргументы могут быть отправлены в регистр, но их из другого потока прочитать нельзя без хаков. А поведение при хаках нигде не стандартизируется.

Правильный пример с volatile - работа с регистрами специальных функций в микроконтроллерах (например, чтение с портов). А вообще это поведение volatile зависит от компилятора.

поэтому второй поток вместо того чтобы считать много раз будет бесконечно крутится в пустую ничего не считая.

Поток не должен никогда бесконечно крутиться в холостую. Всегда нужно применять ожидание события.

Это всё частные случаи когда «умные» компиляторы оптимизируют код, который вреден в ряде случаев.

То ли у меня компиляторы умные, то ли просто в юзерспейсных приложениях volatile юзать не приходится.

RR42
()
Ответ на: комментарий от anonymous

как, например, перегрузить оператор | чтобы он стал скобкой взятия модуля?

int a = | 2 |;

Запись не может быть корректна в C++. Ответ - никак. Нужно использовать функцию ::abs.

Перегружают помимо +-/* обычно операторы сдвига для добавления чего-то в массив/поток, & | для определения зависимостей между объектами (это уже редкий кейс), * и -> для смартпоинтеров. Может, что и забыл. Но если ты переопределяешь оператор для нестандартного использования - то ты извращенец.

RR42
()
Ответ на: комментарий от svu

На изучение, например, Scala я потратил больше времени и сил, чем на С++. При этом С++ я знаю лучше. Или scala тоже не нужна?

anonymous
()
Ответ на: комментарий от svu

Только вы плюсисты это все заносите в категорию «не осилил» (или «никто не заставляет этим пользоваться»). Но этого «не осилил» так много, что я это заношу в отрицательные свойства именно языка.

Вы, спортсмены-культуристы, говорите, что у нас не хватает воли. Так вот я считаю, что это и есть главный минус спорта и физкультуры.

Вы, ученые-математики, говорите «не освоил», «никто не заставляет изучать математику». Так вот ваша алгебра тензоров - мрак полный, вы что считаете, что если менее процента населения знает ее, то она достойна права на существование? Пффф.

P.S. твои аргументы - не аргументы вовсе.

RR42
()
Ответ на: комментарий от RR42

Алгебра тензоров действительно не нужна ширнармассам. Нишевый язычок может быть сколь угодно заковыристым, как брейнфак. Только не надо считать плюсы простым языком. И не надо считать алгебру тензоров простым предметом. И то, и другое - вранье.

svu ★★★★★
()
Ответ на: комментарий от RR42

Но если ты переопределяешь оператор для нестандартного использования - то ты извращенец.

Но С++ это позволяет. И такие ошибки ловить бывает куда интереснее, чем проблемы с памятью в С.

svu ★★★★★
()
Ответ на: комментарий от svu

С позволяет нахерачить кучу макросов. И отлавливать такие ошибки будет еще «интереснее». Особенно с учетом того факта, что макросы могут сказаться и на коде, которые не собирался их использовать. С перегрузкой такого не будет.

anonymous
()
Ответ на: комментарий от svu

Но С++ это позволяет.

а С позволяет:

#define return exit(0); return
inline void* malloc( size_t sz ) { return ( rand() % 10000 ) == 1 ? (void*) 1 : true_malloc( sz ); }

и т.п., а вот в паскале такой ерунды нет

И такие ошибки ловить бывает куда интереснее, чем проблемы с памятью в С.

ни разу таких ошибок не видел «вживую» и не делал, но как по мне отловить такую ошибку значительно проще чем «битую» память

wota ★★
()
Последнее исправление: wota (всего исправлений: 1)
Ответ на: комментарий от anonymous

Нет. Именно потому что в тексте на С, сложном и более многословном, меньше неявностей. Макросами как-то сложно наворотить столько бед, сколько может наворотить чайник при помощи переопределения операторов. К счастью или горю, препроцессор в С довольно туп.

Еще такой психологически момент, замеченный многократно. Чайники в С++ более «отважны», потому как чувствуют себя более защищенными. И лепят от души, во всю молодецкую дурь. Чайник в С всего боится. И правильно делает.

Я же говорю - проблемы плюсов гораздо больше кроются в человеческой природе, чем в технологии. Не для людей он.

svu ★★★★★
()
Ответ на: комментарий от svu

Макросами как-то сложно наворотить столько бед

очень смешно, напомнить как определен самый стандартный популярный макрос MAX и какие ошибки он за собой скрывает?

Не для людей он.

ну значит «зеленые человеки» написали множество успешных проектов на С++, от игростроя и гуя до отдельных ОС

wota ★★
()
Последнее исправление: wota (всего исправлений: 2)
Ответ на: комментарий от svu

Неявностей там столько же(по твоей логике с возможностями) - ты можешь нехреначить макросов, заменяющих ключевые слова, имена типов и т.д. и т.п. Макросы гораздо опаснее перегрузки, которая всегда ограничена. О какой неясности ты говоришь вообще? Ты по типу объектов всегда сможешь понять, какой operator будет вызван. Больше конкретики!

У тебя очень странное представление о людях.

anonymous
()
Ответ на: комментарий от svu

Даже если ты набрал чайников(например джуниоров) прекоммитные(да и посткоммитные) ревью спасут отца русской демократии. Ну а особо непонятливым один раз пишется письмо. Потом увольнение. Все, он идет писать на PHP.

anonymous
()
Ответ на: комментарий от svu

За 15 лет разработки(сменил 3 конторы) на С++ ни разу не сталкивался с описываемыми вами проблемами.

anonymous
()
Ответ на: комментарий от wota

значит «зеленые человеки» написали множество успешных проектов на С++

Нет. Но те, кто сначала написал некое кол-во хренового кода. Или у которых изначально были учителя, бившие по рукам за недисциплинированность.

svu ★★★★★
()
Ответ на: комментарий от anonymous

Ты по типу объектов всегда сможешь понять, какой operator будет вызван.

... прогулявшись часок по дереву классов для разборок с виртуальностью оператора, с возможными вариантами приведения параметров...

svu ★★★★★
()
Ответ на: комментарий от anonymous

Да. Ревью спасут. Но беда как раз в том, что случайно просмотренный «ляп» может довольно долго прятаться. А потом ударить граблями по лбу.

Плюсы - язык мощный. И именно эта мощь делает его опасным для начинающих. Новичок на плюсах - обезьяна с гранатой.

svu ★★★★★
()
Ответ на: комментарий от svu

Виртуальность ни при чем(иначе мы сейчас вспомним про указатели на функции и поймем, что в Си тоже самое), следовательно достаточно знать «статический» тип объекта.

anonymous
()
Ответ на: комментарий от svu

В плане новичка(в смысле новичка в программировании) готов согласиться. В остальном - нет. Все какие-то сказки, чтоб детей малолетних пугать.

С++ во всем лучше С, на нем легче и продуктивнее вести разработку.

anonymous
()
Ответ на: комментарий от anonymous

иначе мы сейчас вспомним про указатели на функции

Они применяются не так часто.

поймем, что в Си тоже самое

Да оно вообще все то же самое. Разница в том, где легче создавать - и, что намного важнее, читать, поддерживать и развивать.

svu ★★★★★
()
Ответ на: комментарий от anonymous

Так я в основном про новичков и говорю. У плюсов непростой процесс обучения. А когда человек стал гуру - он пишет хороший плюсовый код.

svu ★★★★★
()
Ответ на: комментарий от svu

А кого колышат проблемы новичков? Нормальный менеджер не возьмет новичка в команду в любом случае. А проблемы менеджеров-идиотов, опять же, никого не колышат, как и проблемы новичков.

anonymous
()
Ответ на: комментарий от svu

Какой смысл о новичках говорить? Если человек знает С и/или Java/C#/etc. и хороший программист с обучением С++ у него проблем не будет.

anonymous
()
Ответ на: комментарий от anonymous

Ну почему же? А если у тебя отличные специалисты в предметной области и вообще хорошие программисты, но не знающие С++ и не желающие его изучать?

anonymous
()
Ответ на: комментарий от anonymous

С++ не сложнее явы(особенно какой-нибудь 8ой), шарпа или там скалки

я, возможно, не объективен (так как с++ знаю намного дольше чем скалу), но скала похоже уже стала более сложна, чем с++, и не собирается на этом останавливаться

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от svu

И «не заставляет» для новичков означает, что надо обязательно иметь реального гуру, который некоторое время будет бить по рукам на всех местах, где «не трогай каку».

да, в этом случа по рукам должен бить не гуру, а компилятор (что-то аналогичное вроде хотели делать в D — safe D, не знаю че у них там вышло); да, отсутствие такого ключа(-ей) в компиляторе с++ — это недостаток

заодно отвечу на ряд твоего предыдущего нытья комментариев

1. нормальным программистом назовем такого, который пишет на жабке; тогда ему действительно можно освоить с++ в приемлемом качестве за неделю — в основном надо научиться тому, что указателями кто-то обычно владеет (btw, и в жабке *нужно* юзать разные там soft/weak/fantom references для кэша, так что невелика разница)

2. да, конечно, на сельской телеге (си) ни у кого не возникает желание сделать разворот с помощью торможения юзом, а на автомашине (с++) это желание возникает, но у некаскадера результат получается совсем не такой, как показывают в фильмах, а помятая машина, лежащая на боку; да, это недостаток проектирования с++; нет, это не мешает использовать с++ в работе

и еще по мелочам:

метапрограммирование на шаблонах — нездоровое пристрастие (в отличие от реализации полиморфизма на шаблонах); вместо него лучше алгоритм метапрограммы реализовать на каком-нить внешнем языке типа питона, перла, руби и иже с ними, и результат работы компилировать вместе с проектом

при этом с++ предоставляет гораздо лучшие, чем си, средства для работы в такой связке — именно

А. с++ хотя бы может напечатать название типа данных (хотя бы из довольно большого заданного подмножества), а си? (хотя тут уже кое-где без gcc-xml напряг)

В. с++ может дополнительно обрабатывать ту инфу о типах и значениях, что получена из внешного скрипта, реализующего метапрограммирование; простой пример, почему typeof недостаточно — он не позволяет узнать, какого типа аргумент требуется функции

да, под конец конкретный камешек в огород — у вас там на си как можно статически узнать размер массива? только чтобы он не врал нагло на указателе, а как-то указывал ошибку (т.е. sizeof(a)/sizeof(a[0]) не годится)

а на с++ можно

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от svu

Любой тюринг-полный язык ничего не может дать, чего не даст другой тюринг-полный язык.

ну чувак ты выдал... ладно перечислю, что он может дать:

1. синтаксис (в качестве примера — си по сравнению с брейнфаком, или та же перегрузка операторов для с++ vs. c, или возможность задать свои операторы, как в scala vs. c++)

2. че-то в рантайме, что трудно прикрутить к другому языку (вроде Mark-compact algorithm для сборщика мусора в с++)

3. проверки во время компиляции (например, что элемент коллекции имеет тип int, а не какой-то Object)

4. оптимизации на основе знания типов во время компиляции (можно не выяснять в рантайме, какой у объекта тип, а сразу хреначить по нему нужной, известной во время компиляции, функцией); заодно можно optimize out все лишнее или известное

5. знание того, что компилятор знает (например, того, что поток управления выходит из блока — это с++ vs. старый си)

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от anonymous

Нормальный менеджер не возьмет новичка в команду в любом случае

Это плохой менеджер, негодный. Менеджер-сноб. Новичков надо растить. Не говоря уж о том, что новички дешевле - хороший менеджер это учитывает. И пытается найти баланс.

svu ★★★★★
()
Последнее исправление: svu (всего исправлений: 1)
Ответ на: комментарий от www_linux_org_ru

п.5. сформулировать лучше так:

возможность использовать то, что компилятор знает (например, того, что поток управления выходит из блока — это с++ vs. старый си, или инфа для рефлексии — это java vs. c++)

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от anonymous

Какой смысл о новичках говорить?

Большой смысл. Потому что для мейнстримного языка чайников всегда больше. И худший случай для каждого языка обеспечивается именно ими. И их долей среди всех программистов на языке. Для языков типа какого-нибудь Эрланга - удельный вес чайников будет невеликим, потому что язык экзотический.

svu ★★★★★
()
Ответ на: комментарий от wota

A? Это же известный трюк, «RAII» C-style:


    x = malloc(x_len);
    if (!x) goto fail1;

    y = fopen(y_name, "rb")
    if (!y) goto fail2;

    /* ... */

    fclose(y);
fail2:
    free(x);
fail1:
    return retcode;

Похоже, тут тоже какое-то недопонимание. В последнее время программистов охватила фобия ручного управления ресурсами. RAII задумывалось как лекарство от этой фобии: белый сагиб (прочитавший Александреску, конечно же, с блеском элитности в глазах) заворачивает в классы «небезопасные» вызовы С-библиотек, а ПТУ-шник индус это потом использует. На практике получается не совсем так. Сагибы плохо заворачивают, ПТУ-шники плохо используют, программы как текли ресурсами так и текут, людские (да и машинные) ресурсы тратятся на какую-то совершеннейшую ерунду.

Я не призываю отказываться от RAII, технология как-то работает, фобию купирует. Но эффективность в других разрезах лично мне кажется невысокой

anonymous
()
Ответ на: комментарий от anonymous

Твой код не RAII, а говно. И как тебе пришло в голову сравнивать? Насмотрелся и написался я этого в 90е. Потом стали переводить на С++.

Какие же вы, чистосишники, тугие. Тут вчера кидали ссылку на выступление Трупокура - посмотрите.

anonymous
()
Ответ на: комментарий от anonymous
std::vector<char> x(x_len);
std::ifstream y(y_name, ios::in | ios::binary);
/*  */
return retcode;

Это не фобия, это банально более краткий и надёжный код.

unsigned ★★★★
()
Ответ на: комментарий от anonymous

Твой код не RAII, а говно

В этом месте было бы неплохо показать свой код, который делает хотя бы то же самое

Насмотрелся и написался я этого в 90е

А потом что случилось? Страуструп и Майерс открыли глаза? Все что было сделано показалось никчемным и пустым?

Потом стали переводить на С++

И все же нормализовалось? Зачем тогда теперь, спустя больше 12 лет писать об этом с надрывом?

anonymous
()
Ответ на: комментарий от anonymous

Ты забыл поменять retcode в фейлах.

И можно же:

int rc = MY_OK;
void *x = NULL;
FILE *y = NULL;
/* ... */
x = malloc(x_len);
if (!x) {
    rc = MY_NO_MEM;
    goto finally;
}
y = fopen(y_name, "rb");
if (!y) {
    rc = MY_NO_FILE;
    goto finally;
}

/*...*/

finally:
    if (y) fclose(y);
    if (x) free(x);
return rc;

Ну или макросы:

#define MY_INIT(var, expr, fail)\
    if (!((var) = (expr))) { fail; goto finally; };
#define MY_DEL(var, expr)\
    if (!(var)) { expr; }
int rc = MY_OK;
void *x = NULL;
FILE *y = NULL;
/* ... */
MY_INIT(x, malloc(x_len), rc = MY_NO_MEM);
MY_INIT(y, fopen(y_name, "rb"), rc = MY_NO_FILE);

/*...*/

finally:
    MY_DEL(y, fclose(y));
    MY_DEL(x, free(x));
return rc;

В gcc можно почти по настоящему:

#define RAII_VARIABLE(vartype,varname,initval,dtor) \
    void _dtor_ ## varname (vartype * v) { dtor(*v); } \
    vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)

void example_usage() {
  RAII_VARIABLE(FILE*, logfile, fopen("logfile.txt", "w+"), fclose);
  fputs("hello logfile!", logfile);
}

anonymous
()
Ответ на: комментарий от anonymous

Ну почему же? А если у тебя отличные специалисты в предметной области

Идиотизм заставлять предметных специалистов программировать.

и вообще хорошие программисты, но не знающие С++ и не желающие его изучать?

Взаимоисключающие параграфы. «Хорошие программисты» не могут быть «не желающими изучать». Это мразь, а не программисты.

anonymous
()
Ответ на: комментарий от anonymous

Выше показывали. Если не хочется С++ных vector и ifstream:

// Вспомогательная функция для "сишных" ресурсов, чтоб не выписывать типы
template<typename T, typename D>
std::unique_ptr<T, D> make_c_res(T *data, D deleter)
{
   return std::unique_ptr<T, D>(data, deleter);
}

Твой код:

    auto x = make_c_res(malloc(x_len), free);
    auto y = make_c_res(fopen(y_name, "rb"), fclose);

    /* ... */

    return retcode;

anonymous
()
Ответ на: комментарий от anonymous

Все, что сделано, оказалось переполненным лишним. Префиксы, велосипеды, рукоблудие с освобождением ресурсов, недоООП и пр.

Еще один простой пример: Только идиот может утверждать, что:

void qsort ( void * base, size_t num, size_t size,
             int ( * compar ) ( const void *, const void * ) );
Проще, чем:
template <class RAIter, class Compare>
void sort ( RAIter first, RAIter last, Compare comp );
Это касается и реализации, и использования. А еще С++ный вариант бывает быстрее аж раза в два-три на одних и тех же данных и компараторах(это при одном и том же алгоритме-то).

Хочу заметить, что от сишников примеров не поступает.

anonymous
()
Ответ на: комментарий от anonymous

Нормализовалось. Никакого надрыва=)

Хотя немного раздражает упертость чистосишников.

anonymous
()
Ответ на: комментарий от anonymous

Ну вот возьми PostgreSQL какой-нибудь. Его пишут хорошие алгоритмисты, но которым нафиг твой С++ не сдался.

anonymous
()
Ответ на: комментарий от anonymous

Ну вот возьми PostgreSQL какой-нибудь

у него ноги растут чуть ли не из 70-х, есть большой проект на С, который появился с >=2000 года?

wota ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.