Это правильный код C ++ 0x? - PullRequest
       3

Это правильный код C ++ 0x?

9 голосов
/ 28 сентября 2011

Попробовал это в GCC 4.6, и он компилирует и связывает, но выдает сообщение об ошибке шины во время выполнения на MacOS. VS2010 даже не компилирует его.

Но вопрос в том, должно ли это на самом деле работать в стандартном C ++ 0x?

#include <cstdio>
int (*main)()=[]()->int{printf("HEY!\n");return 0;};

Да, он пытается определить "main" как лямбда-функцию.

Ответы [ 4 ]

14 голосов
/ 28 сентября 2011

Это не действительная программа на C ++, потому что символ main определен не как функция, а скорее как указатель на функцию.Вот почему вы получаете ошибку сегментации - среда выполнения пытается выполнить указатель.

3 голосов
/ 28 сентября 2011

Нет, это не правильно.

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

Логическая проблема заключается в том, что существует разница между функцией и переменной, содержащей указатель на функцию (то, что вы хотите, чтобы main был). Функция имеет фиксированный адрес в памяти, поэтому для вызова функции этот адрес просто вызывается. Указатель на функцию указывает на адрес в памяти, поэтому для вызова функции сначала необходимо прочитать, на что указывает указатель, а затем вызвать этот адрес.

Указатель на функцию имеет уровень косвенности, отличный от функции.

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

0 голосов
/ 28 сентября 2011

Теперь он даже не должен компилироваться. Лямбда-выражение дает тип (функтор). Нет неявного преобразования из типа в указатель на функцию.

В зависимости от компилятора, функция main может иметь связь C ++ или C (это определяется реализацией). Лямбда-выражение возвращает тип C ++ с оператором вызова функции, то есть связь C ++.

0 голосов
/ 28 сентября 2011

Для переносимости между компиляторами и реализациями стандартной библиотеки printf () должен быть std :: printf (), когда #inclusive <cstdio>. И другой материал о недействительном main ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...