LINUX.ORG.RU

выход из функции

 


1

1

смотрю файл xxx.c и вижу такое:

int xxx()
{
    if (x) return -1;
    printf("xxx\n");
}

те явного return 0; нет. обновите плиз мой склероз: это UB или где-то в стандарте явно оговорено что точно будет возвращен 0?

это же не жаба с ее null. вангую UB

★★

Последнее исправление: quester (всего исправлений: 1)

Это UB конечно же. clang когда-то на таком проваливался в код следующей функции.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)

Стандарты вроде как говорят, что UB

C89: Flowing off the end of a function is equivalent to a return with no expression. In either case, the return value is undefined.

C11: If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

Reineke
()

UB

#include <stdio.h>
static int x=0;
static char * str[] = {"xxx\n","xxx\n\n","xxx\n\n\n"};

int xxx(char * str)
{
    if (x) return -1;
    printf(" %s",str);
}
int main(int argc, char *argv[])
{
    printf("\n");
    printf("%d =>",xxx(str[0]));
    printf("%d =>",xxx(str[1]));
    printf("%d =>",xxx(str[2]));
    printf("\n");

    return 0;
}
dron@gnu:~$ gcc t.c -g
dron@gnu:~$ ./a.out 

 xxx
5 => xxx

6 => xxx


7 =>

dron@gnu:~$ gcc t.c -Wall
t.c: In function ‘xxx’:
t.c:9:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
dron@gnu:~$ 

Deleted
()

всем большое спасибо, я так и думал

quester ★★
() автор топика
Ответ на: комментарий от anonymous

Тоже мне проблема - что в r/w/x0 останется...

anonymous
()
Ответ на: комментарий от xpahos

Это только в C++, в C UB.

Так в C и C++ приоритет не на борьбу с UB. Это в других языках позапрещают все подряд, а потом, чтобы реализовать двусвязный список приходится весь код в unsafe оборачивать.

anonymous
()
Ответ на: комментарий от anonymous

В других языках списки есть в стандартной библиотеке.

anonymous
()
Ответ на: комментарий от anonymous

И правда, сколько гибкости открывает это UB, сколько возможностей!

anonymous
()
Ответ на: комментарий от xpahos

В C (и C89 и C99 и C11) тут вполне работает неявное объявление (без прототипирования).
И, конкретно в случае с main, компилятор и не подумает на него жаловаться.

Собственно, я смотрю на int main(void) как на перегиб – именно тут прототип не нужен.

Darth_Revan ★★★★★
()
Последнее исправление: Darth_Revan (всего исправлений: 2)
Ответ на: комментарий от Darth_Revan

К слову, в отличие от стандарта C++, в C можно спокойно вызывать main() как функцию.
Тут отсутствие прототипа начинает играть роль, как видно в безумии коде:

#include <stdio.h>

int main ()
{
    static int init = 1;

    if (init != 0) {
        int   argc = 1;
        char *argv[] = {"--ugliness"};

        init = 0;
        return main (argc, argv);
    } 

    printf ("This is the worst.\n");
    return 0;
}
Но, всё равно, как мне кажется, правильное решение тут – никогда так не писать.

Darth_Revan ★★★★★
()
Ответ на: комментарий от Darth_Revan

я смотрю на int main(void) как на перегиб

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

Я плохо понимаю, зачем для main сделали исключение в виде опционального return. Сомневаюсь, что это облегчает программирование. Разве что демонстрационные программы могут быть на одну строчку короче.

i-rinat ★★★★★
()
Ответ на: комментарий от anonymous

ну так main() это и не main(void)

О том и суть?

а зачем так писать?

Вижу, я зря Но, всё равно, как мне кажется, правильное решение тут – *никогда* так не писать. написал после кода, а не перед…

Darth_Revan ★★★★★
()
Ответ на: комментарий от i-rinat

Чем меньше исключений в правилах, тем они проще.

Тоже верно, но, одновременно с тем, наличие или отсутствие аргументов у main() имеет значение только когда его надо вызвать (не надо так делать).
Да и в плане логики языка int main (int, char*[]) и int main () – это одно и то же, только во втором случае прототип опускается, в отличие от int main (void), кой по идее уже отдельный вызов получается.

А если/когда выкинут из C необязательность прототипирования, тогда int main () автоматически станет более чистым синонимом int main (void) (как в C++ сейчас), т.е. win-win.

Darth_Revan ★★★★★
()
Последнее исправление: Darth_Revan (всего исправлений: 2)
Ответ на: комментарий от Darth_Revan

Да и в плане логики языка int main (int, char*[]) и int main () – это одно и то же

Это одно и тоже (в том числе и с аргументом еще и char **env) потому что как и другие функции с произвольным количеством аргументов они должны работать и так и этак с передачей аргументов через стек. Такой синтаксис языку C дал именно Юникс — передача в стартовую функцию исполняемого бинарника argv, а для удобства _start вычисляет argc и добавляет сформированный env из оговоренного вектора памяти.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Действительно, не подумал.
Тем не менее, явное указание main (void) всё равно получается излишним.

Darth_Revan ★★★★★
()
Последнее исправление: Darth_Revan (всего исправлений: 1)
10 октября 2019 г.

В C это не UB.

anonymous
()
Ответ на: комментарий от xpahos

в C99 int main(void) по стандарту раньше было.

В C99 написано что main должна быть функцией with no arguments (либо с двумя аргументами). int main() это функция with no arguments.

anonymous
()
Ответ на: комментарий от anonymous

Либо ещё как-то (implementation-defined).

envp под это попадает.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.