Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#include<iostream>
int main()
{
std::cout << "Hello, World\n";
}
<...> A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place.
§6.6.3/2: Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.
§3.6.1/5. If control reaches the end of main without a return, it will have the effect of return 0;
err = main();Согласно стандарту такой код запрещен: «The function
main shall not be used within a program.» (3.6.1p3)return внутри, все равно обязана компилироваться (опять же согласно стандарту), но если в процессе выполнения программа доходит до конца тела такой функции (и эта функция не ::main), то это ведет к неопределенному поведению со всеми вытекающими.A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;
A return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument. If the } that terminates the main function is reached, the termination status returned to the host environment is unspecified.
If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.
If the } that terminates the main function is reached, the termination status returned to the host environment is unspecified.
Миф 5: С++ предназначен для больших и сложных программ
int greater(const void* p, const void* q) // трёхстороннее сравнение
{
double x = *(double*)p; // получить значение double с адреса p
double y = *(double*)q;
if (x>y) return 1;
if (x<y) return -1;
return 0;
}
int greater(const void* p, const void* q) // трёхстороннее сравнение
{
return *(double*)p - *(double*)q;
}
Мне меньше всего нравится qsort() из стандартной ISO библиотеки C:
Зачем так усложнять?А мы не получим ноль из-за округления там, где его не должно быть? Что будет, если разность больше максимального числа, представимого в int?
код функции std:sort() известен априори компилятору C++. А для C это на усмотрение разработчика.Это утверждение можно прочитать как: «код std::sort зашивается в компилятор, реализовать собственную сортировку разработчик не может», что мягко говоря не правда.
qsort() — большая и сложная функция, использующая рекурсию. Поэтому компилятор не будет инлайнить вызов этой функции, а без этого он не сможет применить оптимизации, связанные с тем, что он знает значения её аргументов в compile-time (и в частности значение указателя на функцию сравнения).std::sort — это шаблон и для каждого отдельного типа компаратора он инстанцируется в отдельную функцию. Грубо говоря, при вызове std::sort(v.begin(), v.end(), std::less<int>{}) вызывается, условно, функция sort_with_std_less, а при вызове std::sort(v.begin(), v.end(), std::greater<int>{}) — другая функция, скажем, sort_with_std_greater.qsort — это самая обычная, простая функция, поэтому при её вызове с любыми параметрами будет всегда выполнятся один и тот же код — тело этой функции. К слову, y std::sort начинаются абсолютно аналогичные проблемы, если вместо функционального объекта ей в качестве компаратора подсовывать указатель на функцию.-fno-exceptions, т. к. и rom, и ram совсем маленькие. Неплохая статья на тему использования c++ на avr — kibergus.su/en/node/92.-fexceptions, приведет к вызову abort(), что тоже не самое приятное поведение (например, при использовании сторонней библиотеки). try {
f1();
} catch (Exception) {/*обработка ошибки 1*/}
try {
f2();
} catch (Exception) {/*обработка ошибки 2*/}
...
try {
fN();
} catch (Exception) {/*обработка ошибки N*/}
status = f1();
if (isError(status)) {/*обработка ошибки 1*/}
status = f2();
if (isError(status)) {/*обработка ошибки 2*/}
...
status = fN();
if (isError(status)) {/*обработка ошибки N*/}
nn_). Остальное для низкоуровневой библиотеки (напомню, единица передачи у которой — массив байт) — не нужно. Это библиотека предоставляет api уровня bsd socket, т. е. ниже только реальный socker api и syscall'ы.shared_ptr<int> p (new int(123));
++ *p;
p.reset();
++ *p; // разыменование нуль-указателя
shared_ptr<int> p(new int(123));
weak_ptr<int> q(p);
p.reset();
if(shared_ptr<int> r = q.lock())
++*r;
else
cout << "сдохло";
shared_ptr<int> p (new int(123));
shared_ptr<int> q = p;
++ *p;
p.reset();
++ *q; // разыменование валидного указателя
Пять популярных мифов про C++, часть 2