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»

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

мнение

прочитай про auto в C и в C++11

Stil ★★★★★ ()

Видимо не стоит компилить компилятором C++11 такой древний код, где используется Сишное auto.

sol_linux ★★ ()

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

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

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

svu ★★★★★ ()

А зачем в чистом цэ было ключевое слово, приводящее к дефолтному поведению? Особо вежливая форма языка что ли?

imtw ()

наше мнение, что auto в C не нужно, и там его использует только К.О.

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

а хрен его знает. Это было лет 40 назад, до стандартов. Мне искать лень.

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

А зачем в чистом цэ было ключевое слово, приводящее к дефолтному поведению? Особо вежливая форма языка что ли?

ЕМНИП auto оно всегда в стеке, а вот без этого слова - на усмотрение компилятора. Может и в регистр засунуть. Иногда это не нужно. (что-то вроде volatile)

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

Иногда это не нужно.

Для ассемблерных вставок что ли? Если компилятор такой умный, что некоторые переменные сам засовывает в регистры, почему бы ему это поведение не отключать, если в функции есть ассемблерная вставка. Но смысл в общем ясен.

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

Си вообще продуманностью не отличается.

В B не было типов, поэтому писали «auto x;». В си стали писать «auto int x», и, видимо, лишь потом поняли, что auto уже лишний, но выбрасывать было поздно.

А вот зачем он в C11 - я действительно не понимаю.

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

ЕМНИП auto оно всегда в стеке, а вот без этого слова - на усмотрение компилятора. Может и в регистр засунуть.

Нет такого в стандарте.

unsigned ★★★ ()

Открытие Америки

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

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

Этого нет также в K&R (по крайней мере, во 2-м издании), так что источник утверждения вообще не ясен.

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

Для регистров есть регистровые переменные (register). Как раз-таки в этом случае использование регистров отдается на откуп компилятору.

LongLiveUbuntu ★★★★★ ()

auto int

по умолчанию в си все локальные переменные автоматические поэтому запись auto int и int равнозначны, так же как запись int равнозначна записи signed int, то есть в случае си мы просто явно это указываем в случае с++ реализация искажена я потестил и вот что либо мы пишем просто auto и обязательно инициализируем перменную и в зависимости от его значения подставляется тип либо пишем auto int и при этом как бы это не смешно было компилятор пытается применить тип 2 раза сначала int а потом пытается расчитать от значения и получаем ошибку так как int int i=2; это fail. Вывод да сломали, но такая поломка не критична.

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

Для ассемблерных вставок что ли?

угу.

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

глобально что-ли? Или в пределах функций?

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

В пределах функций. Но можно и глобально: любители asm-вставок должны страдать.

imtw ()

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

И да, в С++ уже давным давно есть что-то типа
[code=cpp]
extern «C»{
}
[/code]

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

В B не было типов, поэтому писали «auto x;». В си стали писать «auto int x», и, видимо, лишь потом поняли, что auto уже лишний, но выбрасывать было поздно.

ну не совсем лишний, есть ещё static и register. А без auto по умолчанию.

А вот зачем он в C11 - я действительно не понимаю.

а я уже задолбался без него писать. Auto позволяет объявить переменную «неизвестного» типа, т.е. такую, тип которой задаётся rvalue, а не вручную. Такие переменные частенько нужны, и довольно удобны. (конечно на самом деле, их тип вполне известен на этапе компиляции, просто раньше это записать было невозможно).

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

ЕМНИП auto оно всегда в стеке, а вот без этого слова - на усмотрение компилятора. Может и в регистр засунуть.

Нет такого в стандарте.

ага. Эта такая задумка была у K&R, но… Не нужно оказалось.

drBatty ★★ ()

auto int

однозначно на ГК

x0r ★★★★★ ()

Даже ANSI C и C++98 несовместимы. В C99 добавили пачку фич, несовместимых с C++ (например, variable arrays), в C11 ещё досыпали. Ну и плюсисты решили не оставаться в долгу :)

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

Для регистров есть регистровые переменные (register). Как раз-таки в этом случае использование регистров отдается на откуп компилятору.

хочешь сказать, что автоматические переменные всегда в стеке лежат? register - это всего лишь _подсказка_ компилятора, что эту переменную неплохо-бы в регистр. Как и auto (изначально). А вот если подсказок нет, то компилятор должен сам голову ломать.

drBatty ★★ ()
Ответ на: комментарий от i-rinat

1.5 это double, а float 1.5f

Ой блин, спасибо за исправление.

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

а потом пытается расчитать от значения и получаем ошибку так как int int i=2; это fail. Вывод да сломали, но такая поломка не критична.

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

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

ох лол, чтобы писать:

auto it = myMap.begin();

а на выходе:

std::map<std::string, std::tuple<std::pair<int, float>, std::vector<std::shared_ptr<double>>>::const_iterator it = myMap.begin();

ну и как -> auto еще замечательно.

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

в C11 ещё досыпали

Что интересно, часть несовместимостей таки убрали (те же VLA стали опциональны).

unsigned ★★★ ()

Есть много таких экзотических случаев. Например в С можно обозвать переменную new. Имхо, в реальной жизни эти случаи не встречаются либо тривиально исправляются.

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

создаётся переменная не жёстко прописанного типа, а такого-же >типа, как тип аргумента конструктора.

Ну собственно та и есть в си просто при записи auto int спецификатор auto игнорируется, а в с++ нет вся разница от сюда и ошибка.

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

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

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

А кто сказал что auto замечателен, мы умышленно отдаём право думать компилятору со всеми последствиями, и далеко не всегда это оправданно.

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

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

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

мы умышленно отдаём право думать компилятору

и это здорово, а вот когда мы даем право думать разработчикам компиляторов ( например, gcc со своими вставками для static, счетчиками ссылок в std::string и пр.) - это уже не так здорово

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

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

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

Второй случай и наверное самый распространённый когда компилятор заранее просчитывает значения переменной для оптимизации тогда когда нужен обязательный просчёт её при выполнении.

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

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

ему важнее по умолчанию скорость

ты давно не смотрел ассемблер, который генерит gcc без -O1-3

Вот скажи мне что будет

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

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

нужен обязательный просчёт её при выполнении

примеры в студию.

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

и это здорово

Полностью за, когда это оправданно.

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