Почему C ++ нуждается в модификациях языка для «управления»? - PullRequest
9 голосов
/ 04 мая 2009

Почему компилятор не может написать, что управляет , что должно быть управляемым в коде C ++ (т. Е. Чтобы он был "CLR-совместимым")?

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

У меня есть мысли о некоторых аспектах и ​​о том, что может быть трудно решить, но хорошее твердое объяснение будет высоко оценено!

Ответы [ 11 ]

12 голосов
/ 04 мая 2009

Я бы пока не соглашался с ответами.

Основная проблема, которую нужно понять, заключается в том, что компилятор C ++ создает код, подходящий для очень тупой среды. Даже современный процессор не знает о виртуальных функциях, черт возьми, даже функции растягиваются. Процессору действительно все равно, например, что код обработки исключений для разматывания стека находится вне какой-либо функции. Работа процессора в последовательностях команд, с переходами и возвратами. Функции, конечно же, не имеют имен в отношении процессора.

Следовательно, все, что необходимо для поддержки концепции функции, помещается компилятором. Например. vtables - это просто массивы правильного размера с правильными значениями с точки зрения CPU. __func__ заканчивается как последовательность байтов в таблице строк, последний из которых равен 00.

Теперь нет ничего, что говорило бы, что целевое окружение должно быть немым . Вы могли определенно предназначаться для JVM. Опять же, компилятор должен заполнить то, что не предлагается изначально. Нет сырой памяти? Затем выделите большой байтовый массив и используйте его вместо этого. Нет сырых указателей? Просто используйте целочисленные индексы в этом массиве больших байтов.

Основная проблема заключается в том, что программа C ++ выглядит совершенно неузнаваемой из среды хостинга. JVM не глупая, она знает о функциях, но ожидает, что они будут членами класса. Он не ожидает, что в их имени будут < и >. Вы можете обойти это, но то, что вы в конечном итоге, это в основном искажение имени. И в отличие от сегодняшнего искажения имени, этот вид искажения имени предназначен не для линкеров C, а для интеллектуальных сред. Таким образом, его механизм отражения может быть убежден, что существует класс c__plus__plus с функцией-членом __namespace_std__for_each__arguments_int_pointer_int_pointer_function_address, и это все еще хороший пример. Я не хочу знать, что произойдет, если у вас есть std::map строк для обращения итераторов.

В действительности, наоборот, намного проще. Практически все абстракции других языков могут быть удалены в C ++. Вывоз мусора? Это уже разрешено в C ++ сегодня, так что вы можете поддерживать это даже для void*.

Одна вещь, о которой я еще не говорил, это производительность. Эмуляция необработанной памяти в большом байтовом массиве? Это не будет быстрым, особенно если вы положите в них двойные. Вы можете сыграть много трюков, чтобы сделать это быстрее, но по какой цене? Вы, вероятно, не собираетесь получать коммерчески жизнеспособный продукт. На самом деле, вы можете использовать язык, который сочетает в себе худшие части C ++ (множество необычного поведения, зависящего от реализации) с худшими частями виртуальной машины (медленный).

4 голосов
/ 04 мая 2009

Существующий правильный код, то есть код, написанный в соответствии со стандартом C ++, не должен непреднамеренно изменять его поведение.

3 голосов
/ 04 мая 2009

Почему вы не можете скомпилировать собственный код C ++ для CLR?

Да, вы правильно догадались, было бы слишком много компромиссов, которые сделали бы его бесполезным. Я хотел бы назвать только три примера ...

1.) Шаблоны: C ++ поддерживает их, CLR - нет (универсальные значения различны). Таким образом, вы не можете использовать STL, boost и т. Д. В своем коде.

2.) Множественное наследование: поддерживается в C ++, а не в CLI. Вы даже не могли использовать стандартный класс iostream и его производные (такие как stringstream, fstream), которые наследуются как от istream, так и от ostream.

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

3.) Сборка мусора: Большинство приложений C ++ управляют своей памятью вручную (с помощью интеллектуальных указателей и т. Д.), CLR имеет автоматическое управление памятью. Таким образом, стиль «new» и «delete» в C ++ несовместим с «gcnew», что делает существующий код C ++ бесполезным для этого нового компилятора.

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

3 голосов
/ 04 мая 2009

Что ж, C ++ / CLI в основном предназначен для соединения управляемого и неуправляемого кода. Таким образом, вы должны иметь возможность смешивать управляемые и неуправляемые концепции. Вы должны иметь возможность размещать управляемые и неуправляемые объекты в одном и том же коде, поэтому нет возможности обойти отдельные ключевые слова.

2 голосов
/ 04 мая 2009

Прежде всего, различие между «простым C ++» и «управляемым C ++» было намеренным, потому что одной из целей MC ++ было обеспечение моста между существующим кодом C ++ и CLR.

Далее, слишком много функций C ++, которые не вписываются в модель CLR. Множественное наследование, шаблоны, арифметика указателей ... Без четкой линии программисты были бы обречены сталкиваться с загадочными ошибками как во время компиляции, так и во время выполнения.

1 голос
/ 04 мая 2009

Я думаю, это потому, что добавление функций управляемого кода в C ++ сделало бы C ++ медленнее, а компилятор - более сложным. Настолько, что C ++ потеряет то, для чего он предназначен. Одна из приятных особенностей C ++ заключается в том, что с ним приятно работать, он достаточно низкоуровневый и в то же время несколько переносимый. И, вероятно, это то, что Комитет по Стандартам C ++ планирует сделать так. В любом случае, я не думаю, что C ++ когда-либо будет полностью «управляемым», потому что это означает, что программы, написанные на C ++, нуждаются в виртуальной машине для выполнения. Если это так, то почему бы просто не использовать C ++ / CLI?

1 голос
/ 04 мая 2009

Qt framework почти так и делает. То есть у него есть умные указатели, которые автоматически устанавливаются на ноль, когда объект, на который они указывают, уничтожен И все же это родной C ++, после анализа moc (мета-объектный компилятор).

0 голосов
/ 06 апреля 2016

Я согласен с 5hammer! Если бы я оставил Java и другие управляемые языки, это не зря: это ПОЛНЫЙ контроль над компьютером, сам доступ к памяти, управление памятью, контроль над тем, как компьютер будет выполнять мой код, интеграция с библиотеками C (такими как Lua). Если я потеряю эту гибкость, то я просто выйду из C ++ и вернусь к C, а если C тоже станет управляемым, то я перейду к ассемблеру.

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

Основной целью C ++ всегда было Performence. Это один из лучших языков для больших игр. А без этого языкового спектакля множество игр не существовало бы!

0 голосов
/ 05 мая 2015

первое, что нужно рассмотреть, это все, что делает c++ «быстрым», исчезнет. полная система сборки мусора в c ++ практически невозможна. потому что c++ вы можете иметь указатель почти в любом месте кода. Информация о типе среды выполнения становится дорогостоящей, если она не встроена непосредственно в языковая система сама. Вы можете воспользоваться преимуществами настоящей нативной производительности. Шаблон исчезнет. истинные указатели исчезнут. прямой доступ к памяти исчез.

список вещей, которые должны быть соблюдены

1. no direct pointers(pointers will get replace with complex refernces)
2. templates (generics pay for preformance)
3. simple c-style arrays (will get wrapped with array structures)
4. programmer no longer has control of whether data is on the stack or
the heap.
5. garbage collection will be enforced(this will cause the most changes to the syntax)
6. runtime type data will get added extensively to the code.
(larger code size)
7.  inlining will become more difficult for the compiler
(no more inline key word)
8. no more inline assembly.
9. the new langauge by now will become incompatible c code.(unless you go through hoops) 
0 голосов
/ 02 октября 2013

.NET CLR требует, чтобы никакая ссылка на управляемый объект никогда не существовала в любом месте, о котором среда выполнения не знает, за исключением тех случаев, когда объект закреплен; Хорошая производительность требует, чтобы объекты были закреплены как можно меньше. Поскольку .NET CLR не может понять все структуры данных, которые можно использовать в C ++, обязательно, чтобы в таких структурах не было ссылок на управляемые объекты. Было бы возможно, чтобы «обычный» код C ++ взаимодействовал с кодом .NET без каких-либо изменений в языке C ++, но единственный способ, которым код C ++ мог сохранять какую-либо «ссылку» на любые объекты .NET, - это иметь некоторый код на стороне .NET присваивает каждому объекту какой-либо дескриптор и хранит статическую таблицу объектов, связанных с дескрипторами. Код C ++, который хотел манипулировать объектами, должен был бы затем попросить оболочку .NET выполнить некоторую операцию над объектом, идентифицированным дескриптором. Добавление нового синтаксиса позволяет компилятору определять типы объектов, о которых должна знать инфраструктура .NET, и применять к ним необходимые ограничения.

...