- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
enum {
HOST = INADDR_LOOPBACK,
PORT = 6666,
MAX_BUF = 1024
};
struct sock {
int sockfd;
int addrlen;
struct sockaddr_in addr;
} host, client;
int check(int x, char*msg)
{
if (!~x) {
perror(msg);
exit(1);
}
return x;
}
#define QUOTE_(...) #__VA_ARGS__
#define QUOTE(...) QUOTE_(__VA_ARGS__)
#define CHECK(...) check(__VA_ARGS__, QUOTE(line __LINE__: __VA_ARGS__))
int main(int argc, char**argv)
{
struct sock host, client;
host.sockfd = CHECK(socket(AF_INET, SOCK_STREAM, 0)),
host.addr = (struct sockaddr_in){AF_INET, htons(PORT), htonl(HOST)};
CHECK(bind(host.sockfd, &(struct sockaddr)host.addr, sizeof(host.addr)));
CHECK(listen(host.sockfd, 1));
CHECK(client.sockfd = accept(host.sockfd, (void*)&client.addr, &client.addrlen));
printf("connected: %s\n", inet_ntoa(client.addr.sin_addr));
struct {int len; char buf[MAX_BUF];} msg;
while (CHECK(msg.len = recv(client.sockfd, msg.buf, MAX_BUF - 1, 0)) && msg.len) {
msg.buf[msg.len] = 0;
printf("%s", msg.buf);
send(client.sockfd, msg.buf, msg.len, 0);
}
close(client.sockfd);
close(host.sockfd);
return 0;
}
Почему если закоментить 36-ю строчку адрес килента 0.0.0.0?
666_N33D135 13.12.2018 14:36 # −1
tracer 13.12.2018 17:55 # 0
nemyx 13.12.2018 18:38 # 0
guest8 13.12.2018 18:48 # −999
nemyx 13.12.2018 18:53 # 0
Переменные с теми же самыми именами объявлены в функции main (что обычно кладётся в стек):
Если убрать локальное объявление (ту самую 36-ю строку), то у нидлеса программа не может определить адрес клиента.
bormand 13.12.2018 19:02 # 0
И правильно делает! Ибо accept'у некуда писать этот адрес. В отличие от случая с локалкой где всё случайно работает из-за UB'а.
guest8 13.12.2018 19:03 # −999
bormand 13.12.2018 19:04 # +1
В глобалке - ноль. В локалке - UB.
Инициализируйте переменные, блеать.
The addrlen argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by addr; on return it will contain the actual size of the peer address.
guest8 13.12.2018 19:16 # −999
bormand 13.12.2018 19:18 # 0
The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.
guest8 13.12.2018 19:20 # −999
bormand 13.12.2018 19:33 # +1
Х.з., сомнительный ворнинг так то (у студии есть, емнип). Из хедеров много всякого говна торчит, которое ты никогда юзать не будешь. Запрещать все эти имена юзать в качестве локалок, имхо, оверкилл.
А вот в пределах одной функции можно было бы и показать, это на 99% залёт. Но тоже нет.
666_N33D135 14.12.2018 06:50 # 0
nemyx 13.12.2018 19:47 # 0
В обоих случаях результат зависит от деталей реализации.
1. Глобальные переменные.
У секции .data есть инициализированная часть, лежащая в экзешнике, которая забита нулями и прочими начальными значениями (константами и правой частью от выражений типа int x = 42;), и неинициализированная часть, которая создаётся после загрузки (чем она забита, решает загрузчик экзешника).
Кудкудкудкуда ляжет переменная (в инициализированную часть или в неинициализированную), решают кококонпелятор и линкер.
2. Локальные переменные.
Тут всё хуже. В стек может наложить кто угодно. Я помню, как Царь полагался на то, что его промежуточные данные в стеке между вызовами функций сохраняются, и его программа обломалась в Ideone, где какой-то патч типа Propolice или Stackguard чистит стек вилкой.
Значит, у Нидлеса вариант с локальными переменными работает только потому, что по счастливой случайности кто-то в эту область стека положил ненулевые значения.
bormand 13.12.2018 19:52 # +1
6.7.8 Initialization
10) <...> If an object that has static storage duration is not initialized explicitly, then <...> if it has arithmetic type, it is initialized to (positive or unsigned) zero.
nemyx 13.12.2018 19:54 # 0
А с «неарифметическими» что будет?
bormand 13.12.2018 19:55 # +2
- if it has arithmetic type, it is initialized to (positive or unsigned) zero;
- if it is an aggregate, every member is initialized (recursively) according to these rules;
- if it is a union, the first named member is initialized (recursively) according to these rules.
Но это всё касается только static storage duration, на локалки это правило не действует и они наполнены UB'ами.
nemyx 13.12.2018 20:11 # 0
А если другие члены окажутся длиннее первого, то их хвосты можно не инициализировать?
bormand 13.12.2018 20:17 # +1
> если операционка не справляется
Ну это странно... У процесса своей грязной памяти ещё нету, а брать её из других процессов не почистив вилкой - ебучее решето. Хотя какая-нибудь мелкая ось, у которой всё доверенное и без изоляции, в принципе, имеет право.
guest8 13.12.2018 20:47 # −999
bormand 13.12.2018 21:04 # 0
Накладок не будет т.к. только первый именованный из них обязан инициализироваться.
> использовать не 754
Походу да:
Annex F (normative) IEC 60559 floating-point arithmetic
F.1 Introduction
1) <...> An implementation that defines __STDC_IEC_559__ shall conform to the specifications in this annex.
Другим плавучим питухам просто нельзя объявлять это макро.
nemyx 13.12.2018 21:30 # +3
1. MBF (Microsoft binary format, BASIC). Порядок со смещением 128, причём для чисел любой точности. Старший разряд мантиссы подразумевается равным единице, как у IEEE 754. Denormal, inf, NaN не поддерживаются. Знаковый бит где-то в середине.
Если все биты обнулены, то хранится +0.
2. HFP (hexadecimal floating point, IBM System/360). Порядок со смещением 64 для чисел любой точности, основание порядка равно 16, а не 2 (поэтому старший подразумеваемый разряд мантиссы равен нулю). Знаковый бит в самом начале.
Если все биты обнулены, то хранится +0.
3. 48-битный Real в Трубопаскакале. Порядок хранится со смещением 128. Мантисса записывается задом наперёд. Знаковый бит где-то в середине. Старший разряд мантиссы подразумевается равным единице, как у IEEE 754.
Если все биты обнулены, то хранится +0.
Найденные питухи легко обнулять. Нужно найти какой-нибудь посложнее.
У БЭСМ порядок хранился без смещения (т. е. нули соответствовали не минимальному значению, а нулевой степени). Но я пока ещё не прочитал, как там хранилась мантисса.
nemyx 14.12.2018 02:41 # +3
В любом случае, у БЭСМ-6 ноль состоял из нулей. А вот минус нуля (судя по дополнительному коду) не было.
P.S. Какие ещё плавпитухи бывают?
P.P.S. В IEEE 754 описан ещё двоично-десятичный питух. Строится он по тому же принципу, что и двоичный, только бывают ненормальные кодировки порядка для экономии битов.
guest8 13.12.2018 23:38 # −999
bormand 13.12.2018 20:01 # 0
6.2.5 Types
18) Integer and floating types are collectively called arithmetic types.
bormand 13.12.2018 20:24 # +2
Или её ещё нет или вообще нет, а сишку юзать хочется...
Steve_Brown 14.12.2018 11:00 # +1
666_N33D135 14.12.2018 06:27 # 0
всмысле некуда? Я же передал укозатель на сьруктуру?
bormand 14.12.2018 06:34 # 0
З.Ы. Первый вопрос, который должен возникать при вызове незнакомой функции - "а где она берёт длину буфера?"
666_N33D135 14.12.2018 06:52 # 0
Я думал она знает размер сьруктуры.
bormand 14.12.2018 07:02 # 0
А вслепую вроде только gets (функция, запрещённая к использованию) пишет.
666_N33D135 14.12.2018 07:50 # +1
ещё scanf("%s", &s)
nemyx 14.12.2018 14:01 # 0
666_N33D135 14.12.2018 06:30 # 0
sockaddr_in чтоб кастовать меньше
bormand 13.12.2018 19:27 # +1
> if (!~x)
Это что за покемон? Хакерская проверка на -1? Ещё не хватало у знакового числа биты инвертировать...
> && msg.len
Недостижимый код, у тебя CHECK и так вернёт 0. while (msg.len = CHECK(recv(...)), имхо, было бы немного наглядней.
> send(client.sockfd, msg.buf, msg.len, 0);
Уверен, что улетит одним куском? Так можно и байты проебать. Ну и CHECK забыл.
guest8 13.12.2018 19:39 # −999
bormand 13.12.2018 19:58 # 0
> непроверки результтата байнда
Проверен же. Или я слепой?
bormand 13.12.2018 20:34 # +1
Островом сокровищ? Или криптономиконом? Второе, наверное, ближе к теме.
666_N33D135 14.12.2018 06:18 # 0
Я всё проверил.
> TCP (STREAM) у нас с recv
прочитал на rsdn что read/write не рекомендуется
> аут оф баунд
это с чего вдрукк?
guest8 14.12.2018 16:14 # −999
yet_another_one_shit 14.12.2018 17:57 # 0
guest8 14.12.2018 18:16 # −999
guest8 14.12.2018 20:17 # −999
yet_another_one_shit 14.12.2018 20:52 # 0
666_N33D135 14.12.2018 06:24 # 0
но он такой маленький няшка, как его не вставить? ^_^
> Ещё не хватало у знакового числа биты инвертировать
а знаковость как на побитловые опереции влияет?
> Недостижимый код
изначально были проверки на -1 без функции, там нужно было, так и осталось.
> улетит одним куском?
на холокосте да, тестовая программка же.
bormand 14.12.2018 06:32 # 0
Стандарта под рукой нет, но у меня ощущение, что там возможен UB.
666_N33D135 14.12.2018 07:48 # +1
each bit in the result is set if and only if the corresponding bit in the converted operand is
not set). The integer promotions are performed on the operand, and the result has the
promoted type. If the promoted type is an unsigned type, the expression ~E is equivalent
to the maximum value representable in that type minus E.
Обычная побитовая инверсия.
antox 14.12.2018 18:33 # +2
Педанты могут пройтись по упоминаниям sign bit, trap (representation), negative zero и какие там ещё ужасы. Но !~x того не стоит.
yet_another_one_shit 14.12.2018 20:53 # 0
antox 14.12.2018 23:17 # 0
А не стоит - без причин добавлять завязку на особенности реализации.
В мане ведь было: "On error, -1 is returned", а не ~0U. И ничего постыдного нет в очевидной проверке x==-1.
antox 14.12.2018 23:31 # 0
guest8 14.12.2018 23:47 # −999
rOMOCEKCYAjluCT 15.12.2018 00:11 # −102
antox 15.12.2018 00:18 # 0
https://en.wikipedia.org/wiki/Fast_inverse_square_root#History_and_inv estigation
guest8 15.12.2018 02:03 # −999
guest8 14.12.2018 10:07 # −999
zhigolo 14.12.2018 16:45 # 0
Медик?
yet_another_one_shit 14.12.2018 20:56 # 0
guest8 14.12.2018 21:07 # −999
rOMOCEKCYAjluCT 14.12.2018 22:45 # −102
antox 14.12.2018 23:37 # 0
guest8 14.12.2018 16:52 # −999
yet_another_one_shit 14.12.2018 17:51 # +1
Говно виртуольно-вербозное анально-объектно-ориентированое.