Комментарии в Си
Из документации к языку Си на сайте «Микрософта», секция про комментарии, описывается нестандартное расширение спецификации:
Comments beginning with two forward slashes (//) are terminated by the next newline character that is not preceded by an escape character. […] the newline character is preceded by a backslash (\), creating an «escape sequence». This escape sequence causes the compiler to treat the next line as part of the previous line. (For more information, see Escape Sequences.)
The default for Microsoft C is that the Microsoft extensions are enabled. Use /Za to disable these extensions.
То есть в примере ниже, если его скомпилировать в «Визуал Студио», выражение i++; на самом деле будет частью комментарий и не выполнится:
// мой комментарий \
i++;Счастливой отладки!
Добавлено позднее: в компиляторе gcc тоже работает, причём раскрашивается как комментарий в редакторах vim и «Саблайм».
Комментарии 18
#define false ( (__LINE__ & 13) == 13 )
#define if(x) if ( (x) && (rand() < RAND_MAX * 0.99) )
#define j i
?
Так в IDE оно должно быть подсвечено как комментарий.
Ну такое :)
Так это то же самое что просто взять и удалить строку `i++`. И это может быть даже сложнее заметить чем такое комментирование.
Разгадка в том, что автор пишет под другой компилятор, где нет таких спецэффектов.
#include
int main() {
int i=0;
i++;
//\
i++;
printf(«%i», i); // 1
return 0;
}
gcc 9.2.0
Скриншот где //i++// было закоментировано был сделан в //vim// :)
Обратная косая черта — стандартная штука для склейки строк (получения логической строки, logical source line) в Си. Правда, информация о том, должно ли быть такое поведение в комментариях, неоднозначная.
То, что некоторые среды разработки неверно подсвечивают синтаксис, конечно, плохо.
А ещё обратная косая черта может быть заменена триграфом ??/.
Но оставим это хакерство разработчикам обфускаторов. Единственная реальная проблема, выдвинутая в обсуждении, — когда один и тот же код у разных людей компилируется
Перечитал написанное, несколько туманно получилось, верно. Насколько я понял, такое поведение — микрософтское расширение языка, отключаемое специальным ключом. Поддерживается «Студией» и, как мы выяснили, некоторыми другими компиляторами (в комментариях всплыл gcc).
Про триграфы я знаю, но в «Си++17» они удалены и, насколько я помню, из «Си» они тоже пропали (мой clang 11.0 их уже не понимает). Туда им и дорога, конечно.
Я не уверен насколько пример реальный, но полностью синтетическим его тоже на назовёшь. Мне видится две ситуации:
// Может содержать пробел! Например: c:\program files\
TCHAR pf[MAX_PATH];
SHGetSpecialFolderPath(0, pf, CSIDL_PROGRAM_FILES, FALSE);
Эти комментарии в C легальны уже 20 лет ;)
Вероятно, что в MSVC оно попало до принятия C99, отсюда и такой комментарий. Современные компиляторы тоже любят бежать впереди паровоза и внедрять фичи, ещё не принятые комитетом, но уже не включают их по умолчанию.
Цитирую C99:
5.1.1.1 Program structure
2. Each instance of a backslash character (\) immediately followed by a
character is deleted, splicing physical source lines to form logical source lines.
6.4.9 Comments
2 Except within a character constant, a string literal, or a comment, the characters //
introduce a comment that includes all multibyte characters up to, but not including, the
next
multibyte characters and to find the terminating
3 EXAMPLE
«a//b» //
#include «//e» // undefined behavior
// */ // comment, not syntax error
f=g/**//h; // equivalent to f=g/h;
//\
i(); // part of a
/\
/ j(); // part of a
http://www.open-std.org/jtc1/sc22/WG14/www … /n1256.pdf