Неопределенное поведение - обращение к неинициализированной переменной. Говорят в «статике» пытаются победить неопределенное поведение (почти не в тему, но логично).
Неопределенное поведение - обращение к неинициализированной переменной.
какой умный компилятор, это действительно неопределённое поведение. чтобы от него избавиться, достаточно не использовать x внутри f(), но передать x в f() никто не запрещает.
на самом деле оно и в с++17 должно работать, с той ревизии где появились авто-параметры. f(auto x) - это шаблонная функция, но компилятор допишет шаблон за тебя. в с++20 по-моему шаблонные лямбды заехали, они же лямбды с авто-параметрами.
а то, что? придёт неопределённое поведение и пожалуется мамке? тебе от это переменной нужен только тип, использование типа не приводит к неопределённому поведению, ну передай ссылку или адрес. хотя ты можешь написать и так:
Выводит типы всегда. Если я правильно понимаю, нельзя получить скомпилированную функцию, не выведя типов. И полиморфизм там есть в виде мультиметодов. Значит ли это, что задача полного автоматического выведения типов для этого языка полностью решена?
Компилятор D прекрасно понимает, что если из функции может вернуться и значение типа long и значение типа double, то типом результата должен быть именно double.
какое максимальное целое число можно представить в типе long и какое максимальное целое число можно представить в типе double?
жесть какая. что-то мне казалось, что я писал такой код под студию. наверное показалось, в мсвц вообще трудно понять, что он поддерживает, а что нет, наверное перепутал с чем-то.
так же как со знанием типов, только без знания типов. тот же питухон, до того как он рипнулся, компилировал исходный код в двоичный код (байткод), а затем интерпретировал этот байткод. он не интерпретировал текст из файла, программа сначала компилируется, потом интерпретируется. типы при этом выводить не обязательно, просто во время выполнения произойдёт исключительная ситуация если тип не подходит.
машинный код в питухоне получался встраиванием интерпретатора питухона в исполняемый файл. ты запускаешь исполняемый файл, он запускает интерпретатор питухона, интерпретатор питухона интерпретирует питухон.
Ну замечание справедливое и понятно, что они не всегда взаимно отображаются друг в друга без потери точности. Но здесь идет совместимость с сишечкой/плюсами. Пример не самый удачный, согласен, надо было взять short и long, тогда придраться было бы вообще нельзя.
what about the application size? -> By default simple ways to generate a Lisp application often lead to large executables. The executables include the whole Lisp including its library, names of all symbols, information about argument lists to functions, the compiler, the debugger, source code location information, and more. Some compilers generate also largish code (SBCL is an example).
are there ways to shrink application sizes? -> That depends on the Lisp system. Commercial Lisp systems like LispWorks and Allegro CL can. For application delivery, they can remove unused code, remove debugging information, remove parts of the Lisp (libraries, compiler, …) and more.
can Common Lisp systems generate small executables. I mean really small. -> Not really. The executables are either large (CCL) or very large (SBCL). Some Common Lisp systems can generate medium sized executables. But none can really generate small executables.
is there really no way to generate really small executables? -> Years ago compilers were written which generate relatively compact C code without large libraries. But these compilers are not maintained.
The compiler translates Lisp forms and source files into binary code for the host machine. A compiled Lisp function, for instance, is a sequence of machine instructions
ты можешь сделать то же самое в с++, надо только явно указать как ты хочешь решить неоднозначность. например привести получившееся значение к нужному типу.
Ну это же совсем не то. Где здесь вывод типа возвращаемого значения функции? Еще раз:
// ||-- тип функции выводится компилятором D
// ||
// \/
auto square(long num) {
if (num < 0)
return num * num; // здесь возвращаем long
return 0.0; // здесь возвращаем double
}
static assert(is(typeof(square(0L)) == double)); // функция `square` возвращает значение типа double
Нужен код с выводом типа на С++, а в такой код и сишечка умеет.
но вообще return 0.0 когда возвращаемый тип long - это тоже вывод типов компилятором. оно же преобразуется в long, Значит компилятор вывел типы. просто этим не часто пользуются, большинство думает, что вывод типов - это только auto и больше ничего. это не очень очевидно, но весьма полезно.
Ну я надеюсь ты же понимаешь, что в твоем коде выводом типа возвращаемого значения и не пахнет? Там же четко стоит костыль в виде `decltype(std::declval<T>() * std::declval<T>())` и `decltype(0.0)` и по факту идет дублирование кода функции в шаблоне типа возвращаемого значения функции? Если код функции изменится, то нужно менять и шаблонный тип. Твой код это пример явного извращения и так никто в здравом уме писать не будет.
да, а если убрать auto и static_cast, то станет ещё лучше, потому что компилятор тебе ещё сможет что-нибудь сказать про narrowing cast если типы не совсем совпадают. при этом компилятору всё равно надо будет вывести типы чтобы привести один к другому и сделать проверку на их совместимость.
это очень недооценённая фича вывода типов которую мало кто понимает. ну да, не будет auto, очень жаль, не так смузихлёбно как хотелось бы, но работать будет лучше чем до этого.
Только если выражение при поиске в глубину в точке возврата(вроде разрешены должны быть все точки возврата, собственно почему ветвление не решает, либо не всегда решает) приводит к невозможности вывести тип, ровно как и неразрешимый цикл по auto, собственно фсбшные примеры про то и говорят {} не принадлежит типу, а при рекурсии получится цикл по нерешённому auto