Страниц: [1] 2 3
  Печать  
Автор Тема: Типа: все мы знаем приколы си... :о)  (Прочитано 20051 раз)
Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« : Ноября 03, 2006, 04:06:32 pm »

Простой пример:

Вот так:...
#include <Pt.h>

static char* str;

char* f() { return str; }

void any_func()
{
  ...
  PtSetResource( pw, Pt_ARG_TEXT_STRING, f(), 0 );
  ...
}

... будет выдано предупреждение в строке с PtSetResource (cast does not match function type)

А вот так:...
...
void any_func()
{
  char *res;
  ...
  PtSetResource( pw, Pt_ARG_TEXT_STRING, res = f(), 0 );
  ...
}

... нет.

"Я так хохоталься..."
Всё по правилам ! Но - будьте обэрэжни!
Тут в пору ошибку выводить, но компилятор полагается на нас в наших стремлениях усложнить себе жизнь, просто скромно предупреждая... :о)
Записан
Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #1 : Ноября 06, 2006, 09:33:17 am »

А вот ещё вопрос:
Защёл давеча к знакомому. Показал он мне свой код, проконсультироваться. Но тут мне на глаза попалась такая строчка в его тексте (чисто аналогия):
struct S* pS = {0};

Коллеги, объясните мне какой смысл в знаке = и дальше? :о)
ЧТО подразумевается под записью инициализации указателя нулём в фигурных скобках? То что, это аналогично = NULL я понимаю, но что за неявные преобразования и соглашения здесь действуют? Это что-то из нового С99 или расширения gnu? (версия 3.4.х)
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #2 : Ноября 06, 2006, 10:06:59 pm »

Wlad
Коллеги, объясните мне какой смысл в знаке = и дальше? :о)

Создаётся объект размером sizeof(struct S), все поля равняются 0/NULL. pS содержит указатель на  созданный и проинициализированный объект.
Wlad
Это что-то из нового С99 или расширения gnu? (версия 3.4.х)

"The ANSI C Programming Language (Second Edition)" , Copyright 1988 by AT&T  Brian W. Kerninghan, Dennis M. Ritchie.

If there are fewer initializers in the list then members of the structure, the trailing members are initialized with 0.

В С89 были незначительные расширения по данному вопросу.

Я в детстве использовал конструкции типа: struct S aS[20]={{0}}; Сейчас такие конструкции уже deprecated, и компиляторы не держут. 2Wlad: домашнее задание, что делает (делала) эта конструкция.
Записан

lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #3 : Ноября 06, 2006, 10:44:34 pm »

lestat
Создаётся объект размером sizeof(struct S), все поля равняются 0/NULL. pS содержит указатель на созданный и проинициализированный объект.

Это я пробредил. Блин, написал, выключил компьютер, пошел спать, лег и думаю, во фигню написал, встал, решил исправится

Да, в вышеуказанном примере это равносильно = NULL, но если, к примеру будет инициализироваться массив указателей, struct S* pS[20] = {0};, то все указатели будут равны NULL. Т.е. вышеуказанная запись равносильна struct S* pS[1] = {0};
Записан

ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #4 : Ноября 07, 2006, 02:06:02 am »

Wlad

ЧТО подразумевается под записью инициализации указателя нулём в фигурных скобках?


Ваш знакомый или не совсем понимает, что он пишет, или таким образом задрачивает коллег. Ведь многие, не только lestat, могут пробредить увидев структуру там где ее нет. Почему вы не задали этот вопрос вашему знакомому? Любопытно бы услышать, что он сказал бы.

Я у коллег всегда спрашиваю, если вижу что-то непонятное. Они это не любят. Стали читать книжки и стандарты, перестали отвечать "а это, чтобы откомпилилось без варнингов" и прочую ерунду.

edit: если вы не упустили и там конечно не была инициализация массива указателей
Записан
Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #5 : Ноября 07, 2006, 08:02:16 pm »

Инициализировался указатель на структуру.
Причём, когда я спросил, "какето?", мне были паказаны исходники FreeBSD, где народ в массовом порядке применяет то же самое. Вот я теперь и думаю: то ли они на одном символе экономят, то ли исходят из каких-то высших стратегических интиресов?
Если рассуждать в меру моей осведомлённости, то я бы расшифорвывал это так: строится одноэлементный массив, элементов с типом по умолчанию (так, как нет "(тип)" перед "{"? следовательно - это - int), первый и единственный элемент которого (в случае int 32 разряда) совпадает с размером указателя. И потом ЭТО неявно преобразется к NULL-указателю заданного в описании типа.
Но чуйствую неверность в рассуждениях...
Интерес-то в чём: если это просто фича для указателей от гну - похрен мне один лишний символ писать. А если это "часть чего-то большего" - то я об этом почему-то до сих пор не знаю. То есть не могу вывести из тех общих правил языка, которые известны мне, этот частный случай...
Записан
Evgeniy
Jr. Member
**
Offline Offline

Сообщений: 73


Просмотр профиля
« Ответ #6 : Ноября 08, 2006, 01:25:36 am »

Я бы, все-таки, по простоте душевной предположил, что указатель инициализируется ссылкой на область с нулевым значением... Возможно чтобы не встрять в разыменование NULL... Можно, конечно проверить "живьем",.. но не интересно
Если мое предположение о смысле конструкции верно, то ее широкое применение объямняется ремесленным подходом, т.е. было подсмотрено в исходниках какого-нибудь мастера-корифея без понимания смысла использования и воспринято как признак "крутизны". Ну а дальше "Мартышка и очки"...
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #7 : Ноября 08, 2006, 08:49:09 am »

Не знаю что они экономят. ИМО, правильная инициализация указателя
struct S* pS = NULL;
Как по мне, я сразу вижу, что обьект типа указатель (адрес памяти). Второе, NULL не на любой системе обязан быть 0, смысл такой инициализации присвоить "неправильный" адрес, куда нельзя обращаться.

Фигурные скобки - это инициализация списка. Мое первое предположение было, что человек однажды написал что-то типа
int array[5][10] = {0};
И получил предупреждение от gcc, что нету фигурных скобок вокруг инициализатора. Догадался ли он написать "правильно" (в трактовке парней от gcc)
int array[5][10] = {{0}};
или нет, но тем не менее запомнил, что нужны фигурные скобки вокруг инициализаторов. До сих пор их и ставит, везде.

Надо бы поисследовать вопрос... Может я в корне не прав. Исходники фри... Это серьезно... Надо посмотреть при случае, что там люди пишут.
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #8 : Ноября 08, 2006, 09:07:34 am »

ed1k
Догадался ли он написать "правильно" (в трактовке парней от gcc)
int array[5][10] = {{0}};

Эта конструкция, на сколько я знаю, уже не поддерживается.
Записан

Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #9 : Ноября 08, 2006, 10:13:48 am »

ed1k
Не знаю что они экономят. ИМО, правильная инициализация указателя struct S* pS = NULL;

ПОлностью с вами согласен. Это и наглядно и на счёт представимости NULL-а на низком уровне...
Меня терзают сомнения, что я чего-то пропустил. Может "все поют уже давно, а вы всё разговариваете"((с)МЖ)? - вдруг тут нечто важное, а сакральный смысл ускользает от моего мировоспряития? :о)
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #10 : Ноября 08, 2006, 05:58:58 pm »

lestat

конструкция, на сколько я знаю, уже не поддерживается.


$ gcc --version
gcc (GCC) 3.2.2
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cat init.c


int main ()
{
    int a[5][10] = {0};
    a[0][0] = a[4][9];
    return 0;
}

$ gcc -Wall init.c
init.c: In function `main':
init.c:5: warning: missing braces around initializer
init.c:5: warning: (near initialization for `a[0]' )

...

$ cat init.c


int main ()                                        
{                                                  
    int a[5][10] ={{0}};
    a[0][0] = a[4][9];
    return 0;  
}

$ gcc -Wall init.c


--
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #11 : Ноября 08, 2006, 11:21:48 pm »

Это проблемы GCC. См. C99 раздел 6.7.8. Иначе будут проблемы с aggregate initialization.
Записан

ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #12 : Ноября 09, 2006, 02:03:12 am »

lestat
Это проблемы GCC. См. C99 раздел 6.7.8.

Да знаю я Смотрел C99.

lestat
ed1k
Догадался ли он написать "правильно" (в трактовке парней от gcc)
int array[5][10] = {{0}};

Эта конструкция, на сколько я знаю, уже не поддерживается.

Об ГЦЦ и шла речь. Очень этими парнями эта конструкция поддерживается и даже требуется, если у кого требуется компилить "чисто" при -Wall. У нас например требуется, и "боевой" компилятор gcc 2.96...
Записан
Wlad
Участник
*
Offline Offline

Сообщений: 3


Просмотр профиля
« Ответ #13 : Ноября 09, 2006, 03:56:47 pm »

Ну вот, опять ищем под фонарём... :о)
Про массивы я и так знал. Мне, всё же, дюже интересная именно тайна велика про инициализацию указателя нулём в фигурных скобках...
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #14 : Ноября 09, 2006, 06:34:41 pm »

Wlad
Ну вот, опять ищем под фонарём... :о)
Про массивы я и так знал. Мне, всё же, дюже интересная именно тайна велика про инициализацию указателя нулём в фигурных скобках...

Wlad
Причём, когда я спросил, "какето?", мне были паказаны исходники FreeBSD, где народ в массовом порядке применяет то же самое.


Во второй цитате ответ на ваш вопрос. Если человек не может обьяснить, что он написал, а ссылается на какой-то другой код, то гнать такого коллегу в шею.
Просмотрел вчера кое-что из исходников freeBSD - ничего такого не нашел, на удивление опрятный код. Тянуть все и грепить - нет ни времени ни желания.
Простой пример

#include <stddef.h>
#include <stdio.h>

struct S
{
    int a;
    float b;
} my_structS;

int main ()
{
#if 1
    struct S* pS = {0};
#else
    struct S* pS = NULL;
#endif
    printf("some_structS.a = %d", pS->a);
    return 0;
}


--

в двух случаях компиляции производит одинаковый код, который приводит к одинаковому результату:
Segmentation Fault (core dumped)

Evgeniy
Я бы, все-таки, по простоте душевной предположил, что указатель инициализируется ссылкой на область с нулевым значением... Возможно чтобы не встрять в разыменование NULL...


Речь ведь о Си без плюсов? Какие ссылки и разименования?
Записан
Страниц: [1] 2 3
  Печать  
 
Перейти в: