LINUX.ORG.RU

Избранные сообщения xaizek

GitLab

Форум — Talks

У кого-нибудь есть опыт работы с gitlab.com? Какие плюсы-минусы? Что будет, если туда запостить suicide.txt? В связи с действиями РосБредПозора хочется на всякий случай иметь альтернативу.

Имею в виду не развертывание на собственном железе/VPS, а gitlab.com.

 , ,

Klymedy
()

Практическое руководство по соответствию GPL

Новости — Open Source
Группа Open Source

Вашему вниманию предлагается неполный перевод «A Practical Guide to GPL Compliance» 2008.

Перевод вытащен мной из кэша гугла.

По мере роста использования свободного программного обеспечения, в том числе и в коммерческих целях, возникает потребность уделять больше внимания особенностям применения лицензии GPL.

Данное практическое руководство представляет собой подробный и достаточно ясный документ, который позволит компаниям, использующим в своих разработках GPL СПО, избежать возникающих рисков, которые часто неверно квалифицируются за счет неправомерных аналогий с проприетарным ПО.

Документ разъясняет базовые положения GNU General Public Licence и других совместимых лицензий, предоставляя практические рекомендации компаниям как не выходить за рамки лицензионного соглашения.

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

Часть 1 http://tim4dev.com/2014/11/compliance-gpl-1/

Часть 2 http://tim4dev.com/2014/11/compliance-gpl-2/

Часть 3 http://tim4dev.com/2014/11/compliance-gpl-3/

>>> Подробности

 gpl gnu, ,

tim4dev
()

Локальный репозиторий собранных slackware-пакетов

Форум — General

Подкиньте, пожалуйста, команду (или скрипт), которой я могу проиндексировать лок.реп., собранных у меня пакетов (желательно с зависмостями, если для slackpkg) и потом в slaptget и slackpkg+ прописать его

Смотрел вот здесь, но пока что не разобрался (с ключами что ли, подобрать не могу и загвоздка)
http://alien.slackbook.org/blog/introducing-slackpkg-an-extension-to-slackpkg...
https://github.com/gapan/repo-scripts/tree/master/salix

 ,

NK
()

Склейка в define

Форум — Development

Не получается заставить работать «склейку», чтобы избавиться от последнего элемента:

#define CAT(left, right) CAT_EXP(left, right)
#define CAT_EXP(left, right) left ## right

#define HEAD(seq) HEAD_EXP1 seq)
#define HEAD_EXP1(x) x HEAD_EXP2(
#define HEAD_EXP2(x)

#define TAIL(seq) TAIL_EXP seq
#define TAIL_EXP(x)

#define ITER(seq) func(HEAD(seq))  ITER0(TAIL(seq))
#define ITER0(seq) ITER1 seq
#define ITER1(seq) ,func(seq) ITER2
#define ITER2(seq) ,func(seq) ITER1

#define ITER1_END
#define ITER2_END

ITER((a) (b) (c) (d) (e) (f))

На выходе, разумеется, это:

func(a) ,func(b) ,func(c) ,func(d) ,func(e) ,func(f) ITER2

Никак не получается присобачить ##, чтобы приклеить к концу _END

Пробовал так:

#define ITER(seq) func(HEAD(seq))  ITER0(TAIL(seq)) ## _END
и так:
#define ITER(seq) func(HEAD(seq)) CAT(ITER0(TAIL(seq)), _END)
результат один и тот же - deftest.c:79:32: error: pasting ")" and «_END» does not give a valid preprocessing token

Кто мне может подсказать, как мне аки прилепить к концу _END? Или в более широком вопросе - мне нужно проитерировать элементы так, чтобы в конце не было запятой.

 , ,

sambist
()

Однопроходный препроцессор

Форум — Development

Препроцессор си является однопроходным, так?

Тогда как он разворачивает перекрещенную конструкцию из ITER1-ITER2-ITER1...?

#define ITERATE(seq) SEQ(ITER1 seq)
#define SEQ(x) SEQ_I(x)
#define SEQ_I(x) x ## _END
#define ITER1(seq) seq ITER2
#define ITER2(seq) seq ITER1
#define ITER1_END
#define ITER2_END

ITERATE((a) (b) (c))

Можете, пожалуйста, рассказать по шагам, почему оно вообще разворачивается?

 ,

sambist
()

C++ сортировка произвольных типов.

Форум — Development

Как сравнивать произвольные типы? Точнее мне нужно их сортировать, но для этого достаточно научиться их сравнивать.

У меня есть некий темплейт, который принимает произвольное количество классов (окей, я могу менять эти классы, но лучше этого не делать).

foo<C1, C2, C3>
foo<C8, C4>

Я хочу, чтобы foo<C1, C3, C5>::type и foo<C5, C1, C3>::type был один и тот же тип Boo<C1, C2, C5>, порядок не важен, главное, чтобы он был всегда одинаковый.

Единственное решение, которая я вижу - это нумеровать каждый класс. Как нумеровать автоматически, я не знаю.

class C1 {
  constexpr static int value = 1;
}
class C2 {
  constexpr static int value = 2;
}
...

type_info::before почему-то не constexpr.

 ,

Kuzy
()

Что почитать по concurrency и memory model в С++11

Форум — Development

Интересуют atomics, CAS, memory barriers, false sharing detection and prevention, lock-free структуры данных, разные примеры happens before и т.д.

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

Статьи тоже сойдут, хотя я уже их начитался.

 

vertexua
()

Помощь изогнутым рукам: валидация параметров команды в Bash

Форум — Admin

Есть куча команд, которые страшно выполнить неправильно.

Для конкретики выберу только одну: страшно сделать ssh-copy-id без параметра -i (путь до ключа), где путь до ключа - один из заранее определенного набора (~/.ssh/valid_key_1.rsa.pub, ~/.ssh/valid_key_2.rsa.pub).

Можно ли как-нибудь в баше сделать так, чтобы он валидировал все вводимые команды, и если ssh-copy-id запущен с неверными параметрами - не давал бы выполнить такую команду?

 ,

stevejobs
()

Есть ли желающие сделать программу бесплатно?

Форум — Mobile

Хотел бы сделать программку под Андроид, но программировать не умею вообще. Поэтому нужен программист доброволец. Я выступлю как дизайнер доброволец. Что с моей стороны, дизайн и стиль программы. Суть ее функционала. Юзабилити. Тестирование на работоспособность с точки зрения фотографа. Идейная разработка всевозможных фич., по бОльшей части. Решения дилемм будут по мере поступления задач. К примеру делаем фотокамеру. Я рисую скин и все кнопки во всех их вариациях, по требованию программиста. Придумываю концепцию и удобство камеры. Программист собирает. Там может быть одна кнопка затвора и все. Главное что старт положен. Позже сделаем версию 2 и тд.

Если, нет возможности именно под Андроид, то предлагайте другие варианты. Вэб, офф приложения под Винду., игры.... Вс что душе угодно. Может и сойдутся взгляды на чем-то.

«Умники» типа - «ты сделай а мы посмотрим», или - «я сделаю тебе за 30 000 уе»., идут лесом.

 , ,

Explastizin
()

gcc странно инициализирует std::vector внутри структурки

Форум — Development

(На работе меня игнорируют, так что спрошу здесь.)

Требуются люди со скиллом C++ Standard Interfacing V.

Explain:

$ cat cpp.cpp
#include <vector>

struct A
{
    std::vector<int> v;
};

struct B
{
    B()
#ifdef WITH_INIT
    : a()
#endif
    {}

    A a;
};

int main()
{
    B b;
    b.a.v.push_back(42);
}
$ g++ -O0 -S -o cpp.s.0 cpp.cpp

$ g++ -O0 -S -o cpp.s.1 cpp.cpp -DWITH_INIT

$ diff -u cpp.s.0 cpp.s.1
--- cpp.s.0   2014-08-26 15:42:19.635177434 +0300
+++ cpp.s.1   2014-08-26 15:42:25.295177509 +0300
@@ -80,6 +80,12 @@
    subq   $16, %rsp
    movq   %rdi, -8(%rbp)
    movq   -8(%rbp), %rax
+   movq   $0, (%rax)
+   movq   -8(%rbp), %rax
+   movq   $0, 8(%rax)
+   movq   -8(%rbp), %rax
+   movq   $0, 16(%rax)
+   movq   -8(%rbp), %rax
    movq   %rax, %rdi
    call   _ZN1AC1Ev
    leave 

Мне интересно, это gcc/libstdc++ бажит, или там нечто в стандарте позволяет так делать?

 , , ,

ilammy
()

Оптимизация ssh для проброса иксов

Форум — Desktop

Как оптимизировать трафик при пробросе графических приложений по ссш?
Пинги мелкие и отклик вполне устраивает, даже видео в браузерах иксы умудряются пускать сразу на клиент в обход сервера, а вот просто картинка с приложений при изменении жутко тормозит (канал 50-100мб/с), хотя это может быть ещё из-за кривых приложений, так как тот же гимп или инкскейп при работе с картинкой никаких проблем не встречает (сразу, по ходу отправляет на клиент весь холст), а хром при прокрутке страницы перерисовывает каждый кадр заново. Собственно, сабж - как оптимизировать трафик по ссш и иксам (или хотя-бы хромиум/iceweasel (с плавной прокруткой вообще ад - оно перерисовывает _все_ промежуточные кадры))? Проброс рабочих столов не предлагать, ибо разные мониторы (fullhd на 1366*768 кидать не Ъ), только отдельное приложение, общий (в том числе иксовый) буфер обмена и таскай&кидай крайне важны.

PS: запускается и так по ssh -XC

 ,

alltiptop
()

А какой самый простой алгоритм построения треугольника серпинского вы знаете?

Форум — Development

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

Упд: возможно я путаю треугольник серпинского с треугольником паскаля, т.к. слабо шарю в этой теме.

 

Deleted
()

Syncthing 0.9 — программа для синхронизации и резервного копирования

Новости — Open Source
Группа Open Source

Состоялся очередной выпуск Syncthing — открытой кросслатформенной программы для синхронизации и резервного копирования. По своим возможностям она аналогична BitTorrent Synс: заявлена синхронизация файлов между узлами в P2P-сети без участия сервера. Для этого используется собственный открытый протокол BEP («Block Exchange Protocol»).

Возможности программы:

  • Синхронизация директорий и файлов по дате последнего изменения (пока без поддержки версионности).
  • Поддержка синхронизации на уровне блоков. При малом изменении в большом файле будет синхронизироваться лишь изменившаяся часть.
  • Возможность явно указать, каким узлам будет доступна синхронизируемая директория.
  • Опция «master-slave», благодаря которой другие узлы будут лишь синхронизироваться с данной директорией, но не смогут изменять её содержимое.
  • Управление через отзывчивый веб-интерфейс.
  • Кроссплатформенность. Поддерживаются операционные системы Linux, Mac OS X, Windows, FreeBSD и Solaris. Существует неофициальный клиент для Android.
  • Одинаково хорошая работа в пределах LAN и через Интернет.
  • Безопасность и приватность. Данные хранятся на клиентских машинах, не требуется взаимодействие со сторонним сервером. Поддерживается TLS.
  • Каждый узел в сети идентифицируется по стойкому сертификату.
  • Открытый исходный код приложения и открытый протокол.

Изменения в версии 0.9

  • Утеряна совместимость с предыдущими версиями (0.8.x). Необходимо обновить все ноды до актуальной версии. Обновить придётся весь кластер, поскольку syncthing 0.9 не может обмениваться данными с более старыми версиями. Рекомендуется проводить обновление, когда все ноды синхронизированы. Потребуется полное перестроение индексов для всех файлов. Старые индексы и файлы конфигурации будут сохранены в отдельном каталоге «backup-of-v0.8».
  • Графический интерфейс переведён на различные языки: русский, английский, немецкий, испанский, французский, итальянский, португальский, греческий и шведский.
  • Заметно уменьшено потребление памяти в больших кластерах за счёт несколько возросшей нагрузки на процессор и незначительного снижения производительности.
  • Графический интерфейс стал событийно-ориентированным. Устранена проблема, из-за которой графический интерфейс иногда вызывал чрезмерно высокую нагрузку на процессор.
  • Алгоритм сжатия пересылаемых данных изменён с deflate на LZ4, что заметно разгружает центральный процессор. Сжатие можно отключить через графический интерфейс управления узлом для каждого узла в отдельности.
  • Обновление можно производить прямо из графического интерфейса (эта функция пока не поддерживается в версии для Windows).
  • Обновлен формат идентификаторов нод, для проверки добавлены контрольные суммы.
  • Больше не синхронизируется время изменения каталогов (однако, не исключено, что это будет когда-нибудь включено вновь).
  • Если включено версионирование файлов, каталог .stversions не будет расползаться по всем узлам, а храниться только в корне репозитория. При обновлениях придется чистить содержимое этого каталога вручную.
  • Устранена порция мелких ошибок и недоработок. Разумеется, добавлены новые.

Доступны готовые сборки под все основные десктопные платформы, скриншоты, руководство по быстрому запуску и прочая документация.

>>> Подробности

 , ,

anonymous
()

Удалить одинаковые по размеру файлы

Форум — General

Суть в следующем. Есть два каталога с одинаковыми именами каталогов и файлов внутри. Некоторые файлы и каталоги совпадают по имени и размеру с такими же в соседнем каталоге, некоторые нет.

Нужно удалить совпадающие по хэшу md5 файлы во втором каталоге.

Каким образом я могу это сделать?

Chillwood
()

Релиз SimpleScreenRecorder 0.3.0

Новости — Open Source
Группа Open Source

SimpleScreenRecorder, несмотря на название, включает в себя расширенные возможности и настройки для записи экранного видео, неполный список из заявленного:

  • Интерфейс на Qt;
  • Быстрее VLC и ffmpeg/avconv;
  • Запись целого экрана либо его части, запись OpenGL приложений напрямую (как это делает Fraps на платформе Windows);
  • Более точная синхронизация видео со звуком (в сравнении с VLC и ffmpeg/avconv);
  • Полная поддержка многопоточности;
  • Остановка и возобновление записи по хоткею или через иконку приложения в трее;
  • Отображение статистики во время записи: размер файла, время записи, частота кадров, битрейт и т.д.;
  • Предпросмотр записанного во время записи - не нужно тратить время на перепросмотр материала;
  • Экспериментальная поддержка «live streaming»;
  • Универсальные настройки по-умолчанию;
  • Всплывающие подробные подсказки практически ко всему;

Новое в версии 0.3.0 :

  • Добавлена поддержка профилей;
  • Новая, более гибко настраиваемая система записи OpenGL;
  • Улучшена поддержка хоткеев при использовании XInput2;
  • Улучшен синхронайзер;
  • Нативная поддержка моно микрофонов;
  • Добавлено определение источника ALSA;
  • Частично переписан бэкенд выхода;
  • Улучшен алгоритм для обработки событий манипулятора мышь;
  • Новые иконки;
  • Исправления ошибок;

Есть пакеты для дистрибутивов: Ubuntu, Arch Linux, OpenSUSE, Debian, Gentoo, Fedora. Простая компиляция и установка для других дистрибутивов.

Ссылка проекта на GitHub с инструкциями по компиляции и списком зависимостей.

>>> Официальный сайт

 ,

VimCasts
()

Расшифровка CPU флагов (онлайн вариант)

Форум — Web-development

Добрый день, однажды меня стуктуло что нельзя так больше жить и не знать что значит тот или иной флаг при запросе

grep -m 1 flags /proc/cpuinfo
, и вооружившись в начале wiki, затем гуглом, сайтом интела (по ним было больше всего пробелов в вики) и гитхаб профилем некого torvalds.. был сваргован на коленке сей ресурс cpu.pexil.net.

Аналогов я не нашел, но наверное плохо искал. Если кто знает ресурс без поиска ctrl+F или через awk/grep, поделитесь пожалуйста, итогом же будет или развивать и наполнять его (сейчас там по многих краткое описание) или удалить.

З.Ы, если сие сообщение кому-то что-то все таки, да нарушило - грохните его. Ответ из freebsd тоже распарсивать умел..

 , , ,

nikitasius
()

Vim FTP

Форум — Web-development

Здравствуйте, Подскажите, есть ли для vim ftp-плагин, например как у Sublime Text 2, с возможностью выгрузки по сохранению?

Спасибо

 ,

XTishka
()

Си и замыкания

Форум — Development

Я тут как-то услышал, что Си поддерживает локальные функции. Сначала не верил, потому, что в плюсах это не работает, однако проверил и был удивлен. Но потом попытался замыкание, и оно тоже заработало. Это конечно хорошо, но почему это работает? Разве локальные функции(в примере «a» и «b») не создаются в стеке и не должны разрушаться по выходу из глобальной функции(в примере «foo»)?

#include <stdio.h>

int (*foo(int key))(int){
	int a(int x){
		return x+1;
	}
	int b(int x){
		return x-1;
	}
	if (key == 0)
		return a;
	else
		return b;
}

int main(){
	int (* f1)(int) = foo(0);
	int (* f2)(int) = foo(1);
	printf("%d %d\n",f1(5),f2(5));
	return 0;
}

 , ,

Aswed
()

А давно такое по стандартам собирается?

Форум — Development
void
test(void)
{
    return test(); /* wtf? */
}

int
main(int argc, char *argv[])
{
    return 0;
/* UPD: return test(), 0; тоже вполне себе ок */
}
$ gcc -std=c99 -Wall x.c
$ gcc -std=c89 -Wall x.c
$ gcc -ansi -Wall x.c

Обнаружил это в objc/clang, во думаю наконец удобно сделали, мало того, что форварды не надо объявлять, так еще и return void работает, удобно if (shitDidHappen()) return cleanup() делать. Сабж, или это у меня конпелятор кривой?

 , ,

arturpub
()

Тёмные углы C и C++

Форум — Development

Изначально даный пост предназначался для habrahabr, но местные модераторы его не пропустили без объяснения причин:

Увы, ваш топик «Тёмные углы C и C++» не был одобрен и не попал в общую ленту. Причин этому может быть много, но просим не терроризировать службу технической поддержки, так как там вашу статью даже не видели. Расстраиваться тоже не стоит - попробуйте опубликовать что-нибудь еще.

С уважением, Хабрахабр

В связи с этим выкладываю его сюда.

Я, как и многие из вас, работаю программистом. Официально моя должность не привязана к какому-либо конкретному языку программирования, что, кстати говоря, прекрасно, ведь для каждой задачи должны быть свои инструменты. Но довольно часто выбора просто нет (например, из-за особенностей реализации той или иной платформы), в связи с чем подавляющее большинство моих проектов пишутся на C++.

Я не гуру C++. Я не могу похвастаться тем, что с уверенностью распознаю любую шаблонную конструкцию данного языка или возьму и вспомню, что возвращает какая-то редко используемая мной функция из стандартной библиотеки без помощи документации.

Думаю, вы со мной согласитесь, что C++ — язык с очень высоким порогом вхождения. Серьёзно! Я изучаю этот язык уже больше 3 лет, и практически каждую неделю открываю в нём что-то новое и удивительное. Именно об этом «новом и удивительном» и пойдёт речь в данной статье.

За то время, пока я изучал C++, у меня потихоньку накапливались интересные задачки, сниппеты и просто необычные куски кода, которыми я делился с коллегами по работе и знакомыми. У нас даже появилась своего рода традиция — каждый рабочий день с того момента, как я пришёл в компанию, я выкладывал по две новых задачки, которые мы старались по возможности обсудить в перерывах. Постепенно их набиралось всё больше и больше, пока, наконец, я не стал забывать некоторые из них. Именно в тот момент я решил предпринять попытку составления сборника так называемых «тёмных углов» C и C++. Я собрал воедино все те куски кода, что видел до сих пор, дополнил их цитатами из различных стандартов и продолжил копить свою «коллекцию». Изначально моей целью было собрать вместе всего 100 задачек, но я и оглянуться не успел, как их стало уже 200, 300 и вот теперь 400. На самом деле, их даже больше, но на данном этапе я решил ограничиться именно этим количеством.

Итак, представляю Вашему вниманию книгу «C and C++ Dark Corners». Конечно, назвать её книгой можно с натяжкой, ведь это, как я уже и сказал, сборник интересных и для кого-то малоизвестных мест C и С++.

Не откладывайте её в сторону после пары-тройки вопросов, ответы на которые Вы уже итак знаете — я уверен, что хоть какие-то из них заставят Вас задуматься, а ответы на другие могут удивить и даже шокировать.

В качестве примера приведу несколько вопросов из книги:

97. Что попадёт в stdout в результате выполнения след. кода и почему?

#include <iostream>
#include <memory>

#include <boost/smart_ptr/scoped_ptr.hpp>

class Foo
{
public:
 ~Foo() { std::cout << "Foo::~Foo() \n"; }
};

class Bar : public Foo
{
public:
 ~Bar() { std::cout << "Bar::~Bar() \n"; }
};

class Baz : public Bar
{
public:
 ~Baz() { std::cout << "Baz::~Baz() \n"; }
};

int main()
{
 std::cout << 1 << '\n';
 {
  Foo* instance = new Baz;
  delete instance;
 }

 std::cout << 2 << '\n';
 {
  std::shared_ptr<Foo> instance(new Baz);
 }

 std::cout << 3 << '\n';
 {
  std::shared_ptr<Foo> instance(false ? new Bar : new Baz);
 }

 std::cout << 4 << '\n';
 {
  boost::scoped_ptr<Foo> instance(new Baz);
 }

 std::cout << 5 << '\n';
 {
  std::unique_ptr<Foo> instance(new Baz);
 }

 std::cout << 6 << '\n';
 {
  std::auto_ptr<Foo> instance(new Baz);
 }
}

A: Первый случай уже обсуждался ранее – здесь UB в чистом виде (как правило, это приводит к тому, что не будет вызван деструктор производного класса).

Второй случай выдаст на экран следующее:

Baz::~Baz()

Bar::~Bar()

Foo::~Foo()

Почему? Что произошло? Ведь мы же ясно видим, что деструкторы у данных классов не являются виртуальными. Или это один из частных случаев UB? На самом деле, тут всё вполне законно и должно работать так, как указано выше. Посмотрим в документацию к std::shared_ptr и boost::shared_ptr:

http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr

Proper delete expression corresponding to the supplied type is always selected, this is the reason why the constructors are implemented as templates using a separate parameter Y.

http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/shared_ptr.htm

This constructor has been changed to a template in order to remember the actual pointer type passed. The destructor will call delete with the same pointer, complete with its original type, even when T does not have a virtual destructor, or is void.

Третий случай выдаст:

Bar::~Bar() Foo::~Foo()

Почему? Ведь мы только что обсуждали поведение std::shared_ptr! Что тут не так? Вспомните поведение тернарного оператора в C++ — он требует, чтобы второй и третий его операнды были одинакового типа. Более того, каст от базового к производному касту без лишних действий не выполнить, в отличие от обратной ситуации:

#include <iostream>

class Base
{
};

class Derived : public Base
{
};

int main()
{
 Base* first;
 Derived* second;

 Base* foo = second; // Ok
 Derived* bar = first; // Error: invalid conversion from 'Base*' to 'Derived*'
}

Наткнуться на данный момент, связанный с тернарным оператором, можно также и в подобном случае:

#include <iostream>
#include <typeinfo>

template <typename T, typename U>
auto foo(bool b, T t, U u)-> decltype(b ? t : u)
{
 return b ? t : u;
}

int main()
{
 auto _1 = foo(true, 0, 'c');
 std::cout << typeid(_1).name() << '\n';
 auto _2 = foo(false, 0, 'c');
 std::cout << typeid(_2).name() << '\n';
}

Переменные _1 и _2 будут одного и того же типа – int.

Именно поэтому Baz в данном случае будет приведён к Bar.

4, 5 и 6 случаи ничем не отличаются от первого – здесь UB. Надо помнить, что поведение std::shared_ptr отличается от остальных умных указателей.

43. Зачем может понадобиться писать так

#define DO_JOIN(FOO, BAR) DO_JOIN1(FOO, BAR)
#define DO_JOIN1(FOO, BAR) FOO##BAR

вместо

#define DO_JOIN(FOO, BAR) FOO##BAR

A: Потому что препроцессор отработает конкатенацию не так, как того ожидал программист, в том случае, если в качестве аргумента(-ов) мы передадим в макрос DO_JOIN другой макрос:

#include <iostream>

#define DO_JOIN(FOO, BAR) DO_JOIN1(FOO, BAR)
#define DO_JOIN1(FOO, BAR) FOO##BAR

#define MY_MACRO 5

int main()
{
 std::cout << DO_JOIN(1, MY_MACRO) << '\n';
}

Output:

15

#include <iostream>

#define DO_JOIN(FOO, BAR) FOO##BAR

#define MY_MACRO 5

int main()
{
 std::cout << DO_JOIN(1, MY_MACRO) << '\n';
}

error: unable to find numeric literal operator 'operator"" MY_MACRO'

Получается, макрос MY_MACRO не успел раскрыться, в результате чего была попытка провести конкатенацию с 1 и MY_MACRO, что, разумеется, привело к ошибке.

ISO/IEC 14882:2011

16.3.1 Argument substitution [cpp.subst]

1 After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

44. Что попадёт в stdout в результате выполнения след. кода?

#include <iostream>
#include <stdexcept>

struct Foo
{
 Foo() { std::cout << "Foo::Foo()" << std::endl; }
 ~Foo () { std::cout << "Foo::~Foo()" << std::endl; }
};

void foo()
{
 Foo bar;
 throw std::runtime_error("Error");
}

int main ()
{
 foo();
}

A: Зависит от реализации.

// 1

Foo::Foo()

// 2

Foo::Foo() Foo::~Foo()

ISO/IEC 14882:2011

15.3 Handling an exception [except.handle]

9 If no matching handler is found, the function std::terminate() is called; whether or not the stack is unwound before this call to std::terminate() is implementation-defined (15.5.1).

Например, в документации к gcc сказано, что раскрутки стека не произойдёт:

The stack is not unwound before std::terminate is called.

Сборник выкладывается на бесплатной основе, желающим помочь каким угодно образом буду безумно признателен и благодарен. По любым вопросам, рекомендациям и пожеланиям Вы можете обращаться на мой электронный ящик nikita.trophimov@gmail.com. Буду рад услышать абсолютно любое мнение по данному поводу.

В книге ещё много чего можно и даже нужно дорабатывать. Обещаю, что если сообщество проявит хоть какой-то интерес к данному проекту, я продолжу развивать его согласно Вашим предпочтениям и пожеланиям, дополнять новыми задачками и исправлять ошибки. У меня есть много мыслей по поводу улучшения «C and C++ Dark Corners» — среди них добавление тематических разделов, workaround'ы для различных компиляторов и т.д. Главное, чтобы этот интерес был не только с моей стороны.

Жду Ваших положительных и отрицательных отзывов, рекомендаций и, конечно, новых задачек.

Внимательно ознакомьтесь с тем, что указано во «введении», и приятного чтения!

 ,

NikitaTrophimov
()