Я считаю, что тег будет в основном до вас.
Я не понимаю, почему это не должно быть h1, учитывая, что это обычный текст.
Но, анализируя ваше дело , это то, что я бы сделал.
Вариант 1. Используйте h1 и определите его как тег, который будет использоваться для отображения логотипа. Никогда еще он не должен использоваться в dom.
Вариант 2. Создайте новый тег для логотипа, например. Они называются «Пользовательские элементы». Это должно выглядеть примерно так:
var logo = document.registerElement('com-logo', {
prototype: Object.create(HTMLElement.prototype)
});
Затем вам нужно отформатировать логотип с помощью CSS.
Прочитайте этот , чтобы узнать немного больше о пользовательских элементах! :)
Как заметил Оуа, выражение оператора ({ ... })
является расширением GNU; вы не сможете это использовать. Ваше основное выражение близко к тому, что требуется, но не хватает скобок:
#define container_of(ptr, type, member) \
((type *) ((char *)(ptr) - offsetof(type, member)))
Это выглядит чисто для меня. Он распространяется только через две строки для SO.
Макрос записывается так, как он выполняет проверку типа на ptr
. Можно использовать составной литерал вместо выражения оператора и вернуться к простой проверке указателей вместо использования __typeof__
, если компилятор не совместим с gcc:
#ifdef __GNUC__
#define member_type(type, member) __typeof__ (((type *)0)->member)
#else
#define member_type(type, member) const void
#endif
#define container_of(ptr, type, member) ((type *)( \
(char *)(member_type(type, member) *){ ptr } - offsetof(type, member)))
typeof
, когда они доступны, и все же правильны, когда это не так.
– Jonathan Leffler
22 April 2012 в 21:59
ptr
, но инициализируем новое значение с помощью синтаксиса буквенного соединения C99; в частности, это означает, что будут выполняться только неявные преобразования, как работает проверка типа
– Christoph
23 April 2012 в 00:21
void
следует изменить на const void
, так что, если ptr
является const-квалифицированным, тогда компилятор не будет жаловаться на отбрасывание квалификатора const
.
– Alexandros
29 September 2013 в 23:09
Совместимость с ISO C90 с проверкой типа. (Однако предостережение: две оценки ptr
!) [/ G0]
#define container_of(ptr, type, member) \
((type *) ((char *) (ptr) - offsetof(type, member) + \
(&((type *) 0)->member == (ptr)) * 0))
struct container {
int dummy;
int memb;
};
#include <stddef.h>
#include <stdio.h>
int main()
{
struct container c;
int *p = &c.memb;
double *q = (double *) p;
struct container *pc = container_of(p, struct container, memb);
struct container *qc = container_of(q, struct container, memb);
return 0;
}
Тест:
$ gcc -Wall containerof.c
containerof.c: In function ‘main’:
containerof.c:20:26: warning: comparison of distinct pointer types lacks a cast
containerof.c:20:21: warning: unused variable ‘qc’
containerof.c:19:21: warning: unused variable ‘pc’
Мы получаем предупреждение distinct pointer types
для 26, но не 25. Это наша диагностика о неправильном использовании указателей.
Сначала я попытался поставить проверку типа в левую сторону оператора запятой, gcc жалуется на то, что это не имеет никакого эффекта, что является неприятностью. Но, сделав его операндом, мы гарантируем, что он используется.
Трюк &((type *) 0)->member
не совсем определен ISO C, но он широко используется для определения offsetof
. Если ваш компилятор использует этот трюк с нулевым указателем для offsetof
, он почти наверняка будет себя вести в вашем собственном макросе.
0 + offsetof(type, member)
и, вероятно, segfault. Правильно?
– Jo So
10 May 2017 в 10:57
&((type *) 0)->member
- AFAIK, используя выражение deference для NULL-указателя, является UB, даже если он не создает фактический доступ к памяти.
– anton_rh
31 May 2018 в 04:32
offsetof
действительно найдена в компиляторе, то она не может быть неопределенной. Если мы обнаружим, что компилятор использует этот трюк в собственном заголовочном файле, это более или менее легитимизирует использование этого трюка в другом месте (под этим компилятором). Если только он не контролирует такие виды использования, основанные на происхождении (из которого загорается макрос).
– Kaz
31 May 2018 в 17:16
void *
бросков в последовательность, но это не обязательно для любой существующей реализации. Одним из факторов является C11 §6.2.5 ¶28 Указатель наvoid
должен иметь те же требования к представлению и выравниванию, что и указатель на тип символа.48) i> и в сноске 48 говорится: Те же требования к представлению и выравниванию подразумевают взаимозаменяемость в качестве аргументов функций, возвращают значения из функций и членов объединений. i> – Jonathan Leffler 31 May 2018 в 04:37void *
(n стандартного C, потому что дляsizeof(void)
нет значения. GCC рассматриваетsizeof(void)
как1
. – Jonathan Leffler 31 May 2018 в 04:40