 |
Меню |
|
|
|
|
 |
Главная |
|
| Посл.ответ |
Сообщение |
|
Дата: 3 Ноя, 13:06
Простой пример:
Вот так:...
#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 );
...
}
... нет.
"Я так хохоталься..."
Всё по правилам ! Но - будьте обэрэжни!
Тут в пору ошибку выводить, но компилятор полагается на нас в наших стремлениях усложнить себе жизнь, просто скромно предупреждая... :о) |
|
Дата: 6 Ноя, 06:33
А вот ещё вопрос:
Защёл давеча к знакомому. Показал он мне свой код, проконсультироваться. Но тут мне на глаза попалась такая строчка в его тексте (чисто аналогия):
struct S* pS = {0};
Коллеги, объясните мне какой смысл в знаке = и дальше? :о)
ЧТО подразумевается под записью инициализации указателя нулём в фигурных скобках? То что, это аналогично = NULL я понимаю, но что за неявные преобразования и соглашения здесь действуют? Это что-то из нового С99 или расширения gnu? (версия 3.4.х) |
|
Дата: 6 Ноя, 19:06
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: домашнее задание, что делает (делала) эта конструкция. |
|
Дата: 6 Ноя, 19:44
lestat Создаётся объект размером sizeof(struct S), все поля равняются 0/NULL. pS содержит указатель на созданный и проинициализированный объект.
Это я пробредил. Блин, написал, выключил компьютер, пошел спать, лег и думаю, во фигню написал, встал, решил исправится
Да, в вышеуказанном примере это равносильно = NULL, но если, к примеру будет инициализироваться массив указателей, struct S* pS[20] = {0};, то все указатели будут равны NULL. Т.е. вышеуказанная запись равносильна struct S* pS[1] = {0}; |
|
Дата: 6 Ноя, 23:06 · Поправил: ed1k
Wlad
ЧТО подразумевается под записью инициализации указателя нулём в фигурных скобках?
Ваш знакомый или не совсем понимает, что он пишет, или таким образом задрачивает коллег. Ведь многие, не только lestat, могут пробредить увидев структуру там где ее нет. Почему вы не задали этот вопрос вашему знакомому? Любопытно бы услышать, что он сказал бы.
Я у коллег всегда спрашиваю, если вижу что-то непонятное. Они это не любят. Стали читать книжки и стандарты, перестали отвечать "а это, чтобы откомпилилось без варнингов" и прочую ерунду.
edit: если вы не упустили и там конечно не была инициализация массива указателей |
|
Дата: 7 Ноя, 17:02
Инициализировался указатель на структуру.
Причём, когда я спросил, "какето?", мне были паказаны исходники FreeBSD, где народ в массовом порядке применяет то же самое. Вот я теперь и думаю: то ли они на одном символе экономят, то ли исходят из каких-то высших стратегических интиресов?
Если рассуждать в меру моей осведомлённости, то я бы расшифорвывал это так: строится одноэлементный массив, элементов с типом по умолчанию (так, как нет "(тип)" перед "{"? следовательно - это - int), первый и единственный элемент которого (в случае int 32 разряда) совпадает с размером указателя. И потом ЭТО неявно преобразется к NULL-указателю заданного в описании типа.
Но чуйствую неверность в рассуждениях...
Интерес-то в чём: если это просто фича для указателей от гну - похрен мне один лишний символ писать. А если это "часть чего-то большего" - то я об этом почему-то до сих пор не знаю. То есть не могу вывести из тех общих правил языка, которые известны мне, этот частный случай...
|
|
Дата: 7 Ноя, 22:25 · Поправил: Evgeniy
Я бы, все-таки, по простоте душевной предположил, что указатель инициализируется ссылкой на область с нулевым значением... Возможно чтобы не встрять в разыменование NULL... Можно, конечно проверить "живьем",.. но не интересно
Если мое предположение о смысле конструкции верно, то ее широкое применение объямняется ремесленным подходом, т.е. было подсмотрено в исходниках какого-нибудь мастера-корифея без понимания смысла использования и воспринято как признак "крутизны". Ну а дальше "Мартышка и очки"... |
|
Дата: 8 Ноя, 05:49
Не знаю что они экономят. ИМО, правильная инициализация указателя
struct S* pS = NULL;
Как по мне, я сразу вижу, что обьект типа указатель (адрес памяти). Второе, NULL не на любой системе обязан быть 0, смысл такой инициализации присвоить "неправильный" адрес, куда нельзя обращаться.
Фигурные скобки - это инициализация списка. Мое первое предположение было, что человек однажды написал что-то типа
int array[5][10] = {0};
И получил предупреждение от gcc, что нету фигурных скобок вокруг инициализатора. Догадался ли он написать "правильно" (в трактовке парней от gcc)
int array[5][10] = {{0}};
или нет, но тем не менее запомнил, что нужны фигурные скобки вокруг инициализаторов. До сих пор их и ставит, везде.
Надо бы поисследовать вопрос... Может я в корне не прав. Исходники фри... Это серьезно... Надо посмотреть при случае, что там люди пишут.
|
|
Дата: 8 Ноя, 06:07
ed1k Догадался ли он написать "правильно" (в трактовке парней от gcc)
int array[5][10] = {{0}};
Эта конструкция, на сколько я знаю, уже не поддерживается. |
|
Дата: 8 Ноя, 07:13
ed1k Не знаю что они экономят. ИМО, правильная инициализация указателя struct S* pS = NULL;
ПОлностью с вами согласен. Это и наглядно и на счёт представимости NULL-а на низком уровне...
Меня терзают сомнения, что я чего-то пропустил. Может "все поют уже давно, а вы всё разговариваете"((с)МЖ)? - вдруг тут нечто важное, а сакральный смысл ускользает от моего мировоспряития? :о) |
|
Дата: 8 Ноя, 14:58 · Поправил: ed1k
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
-- |
|
Дата: 8 Ноя, 20:21
Это проблемы GCC. См. C99 раздел 6.7.8. Иначе будут проблемы с aggregate initialization.
|
|
Дата: 8 Ноя, 23:03
lestat Это проблемы GCC. См. C99 раздел 6.7.8.
Да знаю я  Смотрел C99.
lestat ed1k
Догадался ли он написать "правильно" (в трактовке парней от gcc)
int array[5][10] = {{0}};
Эта конструкция, на сколько я знаю, уже не поддерживается.
Об ГЦЦ и шла речь. Очень этими парнями эта конструкция поддерживается и даже требуется, если у кого требуется компилить "чисто" при -Wall. У нас например требуется, и "боевой" компилятор gcc 2.96... |
|
Дата: 9 Ноя, 12:56
Ну вот, опять ищем под фонарём... :о)
Про массивы я и так знал. Мне, всё же, дюже интересная именно тайна велика про инициализацию указателя нулём в фигурных скобках...
|
|
Дата: 9 Ноя, 15:34
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...
Речь ведь о Си без плюсов? Какие ссылки и разименования? |
|
Дата: 9 Ноя, 15:55
Просмотрев хидеры SunOS и то как там обьявлен NULL,
могу только предположить, что если тип int короче, чем ширина адресной шины, то ширины нуля может нехватить и при {0} компилятор таки возьмет длинный ноль из нескольких нулей списка. (Хотя вроде бы должен преобразовать типы и расширить ноль). По любому - инициализация указателя с помощью {0} извращение и в корне неправильно, IMHO.
|
|
Дата: 9 Ноя, 19:09
ed1k По любому - инициализация указателя с помощью {0} извращение и в корне неправильно, IMHO.
Q: Should I use NULL or 0?
A: In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days.
If you have to name the null pointer, call it nullptr; that's what it's going to be called in C++0x. Then, "nullptr" will be a keyword.
(c) Bjarne Stroustrup. |
|
Дата: 9 Ноя, 19:16
Раз пошла такая жара, читать от корки до корки.
5.4: What is NULL and how is it #defined?
A: As a matter of style, many programmers prefer not to have
unadorned 0's scattered through their programs. Therefore, the
preprocessor macro NULL is #defined (by <stdio.h> and several
other headers) with the value 0, possibly cast to (void *) (see
also question 5.6). A programmer who wishes to make explicit
the distinction between 0 the integer and 0 the null pointer
constant can then use NULL whenever a null pointer is required.
Using NULL is a stylistic convention only; the preprocessor
turns NULL back into 0 which is then recognized by the compiler,
in pointer contexts, as before. In particular, a cast may still
be necessary before NULL (as before 0) in a function call
argument. The table under question 5.2 above applies for NULL
as well as 0 (an unadorned NULL is equivalent to an unadorned
0).
NULL should *only* be used for pointers; see question 5.9.
References: K&R1 Sec. 5.4 pp. 97-8; K&R2 Sec. 5.4 p. 102; ISO
Sec. 7.1.6, Sec. 6.2.2.3; Rationale Sec. 4.1.5; H&S Sec. 5.3.2
p. 122, Sec. 11.1 p. 292.
5.5: How should NULL be defined on a machine which uses a nonzero bit
pattern as the internal representation of a null pointer?
A: The same as on any other machine: as 0 (or some version of 0;
see question 5.4).
Whenever a programmer requests a null pointer, either by writing
"0" or "NULL", it is the compiler's responsibility to generate
whatever bit pattern the machine uses for that null pointer.
Therefore, #defining NULL as 0 on a machine for which internal
null pointers are nonzero is as valid as on any other: the
compiler must always be able to generate the machine's correct
null pointers in response to unadorned 0's seen in pointer
contexts. See also questions 5.2, 5.10, and 5.17.
References: ISO Sec. 7.1.6; Rationale Sec. 4.1.5.
5.6: If NULL were defined as follows:
#define NULL ((char *)0)
wouldn't that make function calls which pass an uncast NULL
work?
A: Not in general. The complication is that there are machines
which use different internal representations for pointers to
different types of data. The suggested definition would make
uncast NULL arguments to functions expecting pointers to
characters work correctly, but pointer arguments of other types
would still be problematical, and legal constructions such as
FILE *fp = NULL;
could fail.
Nevertheless, ANSI C allows the alternate definition
#define NULL ((void *)0)
for NULL. Besides potentially helping incorrect programs to
work (but only on machines with homogeneous pointers, thus
questionably valid assistance), this definition may catch
programs which use NULL incorrectly (e.g. when the ASCII NUL
character was really intended; see question 5.9).
References: Rationale Sec. 4.1.5.
5.9: If NULL and 0 are equivalent as null pointer constants, which
should I use?
A: Many programmers believe that NULL should be used in all pointer
contexts, as a reminder that the value is to be thought of as a
pointer. Others feel that the confusion surrounding NULL and 0
is only compounded by hiding 0 behind a macro, and prefer to use
unadorned 0 instead. There is no one right answer. (See also
questions 9.2 and 17.10.) C programmers must understand that
NULL and 0 are interchangeable in pointer contexts, and that an
uncast 0 is perfectly acceptable. Any usage of NULL (as opposed
to 0) should be considered a gentle reminder that a pointer is
involved; programmers should not depend on it (either for their
own understanding or the compiler's) for distinguishing pointer
0's from integer 0's.
NULL should *not* be used when another kind of 0 is required,
even though it might work, because doing so sends the wrong
stylistic message. (Furthermore, ANSI allows the definition of
NULL to be ((void *)0), which will not work at all in non-
pointer contexts.) In particular, do not use NULL when the
ASCII null character (NUL) is desired. Provide your own
definition
#define NUL '
| | | |