Ответы пользователя по тегу C
  • Контринтуитивный синтаксис объявления нескольких переменных одного типа?

    По делу уже ответили, приведу лишь интересную цитату от Денниса Ритчи:

    I'm still uncertain about the language declaration syntax, where in declarations, syntax is used that mimics the use of the variables being declared. It is one of the things that draws strong criticism, but it has a certain logic to it.

    Ссылка на интервью
    Ответ написан
    Комментировать
  • Как лучше вносить изменения в стороннюю библиотеку С?

    Непонятно, какие у этой библиотеки есть точки расширения, какие есть интерфейсы. Общий ответ всегда один - форкать, наливать сверху свои изменения и затем портировать их регулярно на свежий релиз. Это самый затратный вариант, но он не требует ничего от библиотеки кроме открытости кода и подходящей лицензии, разрешающей вносить правки без неприемлемых для вас обязательств.
    Ответ написан
    Комментировать
  • Почему программа вообще заходит в цикл и почему тут же завершается при присваивании?

    Ответ для C++
    Не указав инициализатора при объявлении переменной num, вы используете default initialization. Почему? Смотрим по ссылке:
    Default initialization is performed in three situations:
    1) when a variable with automatic, static, or thread-local storage duration is declared with no initializer;

    Это как раз ваш случай.

    Далее:
    The effects of default initialization are:
    ......
    otherwise, no initialization is performed: the objects with automatic storage duration (and their subobjects) contain indeterminate values.

    Итого, согласно третьему описанному случаю, ваша переменная num содержит неопределённое значение (indeterminate value).

    Читаем далее:
    Use of an indeterminate value obtained by default-initializing a non-class variable of any type is undefined behavior (in particular, it may be a trap representation), except in the following cases:
    ...

    Ваш случай не попадает под исключения, следовательно вы схлопотали undefined behavior.

    Что такое undefined behavior? Это значит, что компилятор что хочет, то и генерирует на выходе:
    Compilers are not required to diagnose undefined behavior (although many simple situations are diagnosed), and the compiled program is not required to do anything meaningful.

    Вывод: не делать так, чтобы в программе был undefined behavior.

    Ответ для C
    Не указав инициализатора при объявлении переменной num, вы используете implicit initialization. Смотрим по ссылке:
    If an initializer is not provided:
    - objects with automatic storage duration are initialized to indeterminate values (which may be trap representations)
    ...

    Это как раз ваш случай.

    Читаем далее:
    If an indeterminate value is used as an argument to any standard library call, the behavior is undefined. Otherwise, the result of any expression involving indeterminate values is an indeterminate value (e.g. int n;, n may not compare equal to itself and it may appear to change its value on subsequent reads)

    Итого, у вас либо неопределённое поведение, либо неопределённое значение выражения, если там используется num. Значение в num может даже самопроизвольно меняться между операциями чтения из этой переменной.

    Вывод: не делать так, чтобы в программе встречалось использование indeterminate values.
    Ответ написан
    3 комментария
  • Как включить в статическую библиотеку все зависимости из других стат.библиотек в CMake проекте?

    Nipheris
    @Nipheris Куратор тега C++
    Господи, что ж тут за костыли насоветовали))

    Этого хотелось бы избежать, то есть нужно, чтобы все зависимости от boost были уже включены в mylib.

    Как верно отметил jcmvbkbc , обычно одна стат. библиотека не тащит в себе другую. Более того, такая возможность - включить одну стат. библиотеку в состав другой - мало где существует, я знаю про поддержку такой фичи только в Visual Studio. Ну т.е. это нечто из ряда вон выходящее, а не привычный workflow. По-нормальному вы должны указывать при линковке стат. библиотеки все её зависимости. Следовательно, вопрос в том, как эту информацию о транзитивных зависимостях статической библиотеки передавать и использовать при линковке с ней.

    pkg-config в общем вполне нормальное решение, но это уже не совсем "в рамках CMake".
    В рамках CMake всё делается с помощью target_link_libraries и экспорта симейк-конфига в паре с файлом симейковских таргетов. Например, вот такой незамысловатый скрипт:
    cmake_minimum_required(VERSION 3.5)
    find_package(Boost COMPONENTS system filesystem thread REQUIRED)
    add_library (mylib mysource.cpp)
    target_link_libraries(mylib
    	PRIVATE
    		Boost::system
    		Boost::filesystem
    		Boost::thread
    )
    
    install(TARGETS mylib EXPORT mylib_export)
    export(EXPORT mylib_export FILE cmake/mylib-targets.cmake)

    сгенерирует в поддиректории cmake в директории сборки файл mylib-targets.cmake, где помимо прочего будет следующая любопытная информация:
    # Create imported target mylib
    add_library(mylib STATIC IMPORTED)
    
    set_target_properties(mylib PROPERTIES
      INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:Boost::system>;\$<LINK_ONLY:Boost::filesystem>;\$<LINK_ONLY:Boost::thread>"
    )


    Таким образом, Симейк сообщает потребителям библиотеки mylib, что при линковке с ней нужно ещё добавить бустовские таргеты. Причём благодаря LINK_ONLY это коснётся только процесса линковки, в целом зависимость от библиотек буста будет приватной, как и указано в скрипте. Если поменять PRIVATE на PUBLIC и сделать тем самым зависимость от буста публичной, то LINK_ONLY уйдёт и будет обычное перечисление интерфейсных зависимостей таргета:
    # Create imported target mylib
    add_library(mylib STATIC IMPORTED)
    
    set_target_properties(mylib PROPERTIES
      INTERFACE_LINK_LIBRARIES "Boost::system;Boost::filesystem;Boost::thread"
    )


    Вам остаётся лишь добавить генерацию и установку тривиального конфига (где будет только find_package для буста и инклуд сгенерированного mylib-targets.cmake) и в потребителях делать find_package(mylib). Всё это кроссплатформенно и является стандартной практикой, не делайте лишних извращений со слиянием статических библиотек.
    Ответ написан
    Комментировать
  • Структура и зависимости кросс-платформерного проекта CMake?

    Nipheris
    @Nipheris Куратор тега C++

    Один из моих вариантов решения проблемы:
    Написать скрипт (скорее всего на python, ибо нужна возможность компилировать как из под Windows, так и из под Linux), который будет собирать все зависимости под конкретную платформу, раскидывать по папочкам и генерировать скрипт с путями ко всем нужным библиотекам.

    Поразительно, но вы в точности описали пакетный менеджер Conan (о котором упоминали).

    Написать скрипт (скорее всего на python, ибо нужна возможность компилировать как из под Windows, так и из под Linux)

    Конан написан на Питоне и распространяется как pip-пакет.

    который будет собирать все зависимости под конкретную платформу, раскидывать по папочкам

    https://docs.conan.io/en/latest/using_packages/con...
    Together, these folders are the local cache. This is where package recipes and binary packages are stored and cached, so they don’t have to be retrieved again.


    и генерировать скрипт с путями ко всем нужным библиотекам

    https://docs.conan.io/en/latest/reference/generato...
    Generators are specific components that provide the information of dependencies calculated by Conan in a suitable format for a build system. They normally provide Conan users with a conanbuildinfo.XXX file that can be included or injected to the specific build system.
    Ответ написан
    Комментировать
  • Можно ли использовать переменные в функцие system?

    Nipheris
    @Nipheris Куратор тега C++
    Сесть и поучить C++, это вам не PHP.
    Используйте std::to_string(i) и сконкатенируйте нужную вам строку, или сделайте замену в исходной строке с помощью метода replace у std::string.
    Ответ написан
    1 комментарий
  • Передача по ссылке в C99?

    Ссылки в Си?? Это что-то новое. Я пропустил нововведения?
    Почему работает только 1 вариант?

    Потому что первый вариант компилит код как C++.
    Ответ написан
    1 комментарий
  • Как вывести каждый байт значения типа int?

    Nipheris
    @Nipheris Куратор тега C++
    1. char - знаковый тип. Используйте unsigned char, а лучше std::byte если он доступен вам.
    2. проверьте форматную строку.
    Ответ написан
    Комментировать
  • Можно ли полноценно разрабатывать на С и не прыгать в С++?

    Nipheris
    @Nipheris Куратор тега C++
    Можно ли полноценно разрабатывать на С и не прыгать в С++?

    Да.
    Ответ написан
  • В каких случаях пишут на C вместо C++?

    Nipheris
    @Nipheris Куратор тега C++
    Допустим есть команда профессиональных, финансово-неограниченных, C/C++ программистов, которые предпочитают писать на C++, но были вынуждены выбрать язык C для решения следующих задач....что это за задачи и почему?

    1. Низкоуровневые задачи, где нужно иметь минимум абстракции от оборудования. Я лично хоть и не разделяю анти-C++ настроений Линуса, вполне согласен с тем что ядру полезно быть написанным на Си. В C++ есть довольно много абстракций, влияющих на исполнение кода, есть некоторые вещи "под капотом", которые могут быть недопустимы в низкоуровенвом коде.

    2. Большие проекты, где сложно форсировать code-style. С++ - это такой язык... Он настолько разнообразен, что прежде чем некая команда сядет писать код, она должна выбрать некоторое ПОДМНОЖЕСТВО языка, и использовать его. Иными словами, Плюсы - это большой ящик с инструментами, и вовсе не обязательно (даже вредно) использовать сразу все. Важно отказываться от каких-либо возможностей или практик, особенно устаревших (а таких в C++ немало, "идиоматический" код на C++03 и C++17 - очень разный). Кто не хочет со всем этим заморачиваться (вспомним опять таки Линух - огромный проект с огромным числом участников) - вполне могут выбрать Си. Ведь можно считать, что выбор языка Си - это выбор только необходимого инструментария из того что предлагается в C++ (только помните что сейчас это всё-таки разные языки).

    3. Программирование в сильных ресурсных ограничениях. Например под микроконтроллеры. Хоть в С++ программист "не платит за то чем не пользуется", иногда стандартные реализации различных механизмов недопустимо тяжелы или неэффективны. Например, если у вас очень медленный чип или мало памяти, возможно вы заходите свою собственную реализацию полиморфизма. Какой тогда смысл говорить что вы пишете на C++, если не сможете использовать его механизмы и то, что предлагает компилятор.
    Ответ написан
    Комментировать
  • Как сгенерировать видео с помощью c или c++?

    Nipheris
    @Nipheris Куратор тега C++
    Готовые библиотеки для генерации видео называются - внезапно - кодеками. Вот например почему бы не упомянуть x.264. Есть и куча других. Т.к. почти все они пишутся на C/C++, из этих языков ими наиболее удобно пользоваться.

    Также нужно упомянуть FFmpeg как более общее и комплексное решение. Лучше наверное даже на него сначала посмотреть.
    Ответ написан
  • Как операционная система понимает, сколько нужно очистить память?

    Nipheris
    @Nipheris Куратор тега C++
    Факт 1. malloc и free реализуется не ОС, а рантайм-библиотекой языка C/C++. Да, безусловно, время от времени рантайм библиотека делает системные вызовы для того чтобы получить от ОС адресное пространство, но делается это далеко не на каждый malloc/free.

    Факт 2. Вам нужно чётко понимать, что работаете вы со средствами языка и стандартной библиотеки языка, а не ОС. Если на каком-то устройстве скомпилированная программа на C должна работать без ОС, то и способы реализации функционала malloc/free будут иные.

    Факт 3. Алгоритмы, реализующие работу malloc и free, хранят довольно много служебной информации для себя, в частности размер и положение выделенных блоков. Вы не имеете непосредственного доступа к этой информации, но это не значит что её нет. Её достаточно как минимум для того, чтобы выделять вам новые блоки и корректно освобождать старые. Такие алгоритмы называются менеджерами памяти. Кстати в этой незамысловатой статье на вики написано о так называемой иерархии менеджеров памяти. Если вы ознакомитесь с этим понятием, узнаете наверняка больше, чем из всех ответов вместе взятых.
    Ответ написан
    Комментировать
  • Семантика типов в Си и C#?

    Nipheris
    @Nipheris Куратор тега C#
    Сходство есть, но и различий достаточно. Указатель хранит адрес в памяти, который в общем-то доступен вам для чтения и записи. Вы можете любой int скастить в указатель и попытаться разыменовать его. Врядли ли вы получите от этого что-то полезное, но суть в том что вы МОЖЕТЕ это сделать. Указатель как тип данных лишь даёт вам удобное средство для адресации и типизированной работы с областью памяти.

    Ссылка в .net - вещь значительно более высокоуровневая. Это скорее object identity, а не адрес в памяти. Ссылка не хранит непосредственно адрес объекта в управляемой куче, она хранит его номер, а конкретным адресом в памяти управляет сборщик мусора (так сделано потому, что сборщик имеет право перемещать объекты в памяти, если они явно не закреплены).

    Как уже сказали выше, указатели в C# тоже есть, и они действительно хранят адрес. Но они доступны только в unsafe контексте и не являются средством для everyday-разработки.

    Ссылки в C# концептуально связаны с объектным подходом, ссылка хранит идентификатор объекта и является "ключом" доступа к нему. Ссылка не может непосредственно ссылаться на типы-значения на уровне платформы .net, для этого нужно сначала выполнить boxing значения.

    Сишкном указателю же без разницы, на что он указывает. Если говорить в контексте C++, то программист по сути сам даёт указателям на объекты семантику object identity.
    Ответ написан
    1 комментарий
  • Когда вызывается malloc() или new, то на самом деле вызывается какая-то win api функция?

    Nipheris
    @Nipheris Куратор тега C++
    Когда вызывается malloc() или new, то на самом деле вызывается какая-то win api функция?

    Нет, не всегда. В большинстве случаев не вызывается. Системный вызов осуществляется только если текущий блок, управляемый сишной кучей (т.е. сишным рантаймом) исчерпывается. Если б каждый раз делался системный вызов, вы б не дождались результатов работы вашей программы.

    И при удалении тоже?

    См. выше.

    И вот интересно, а как сделать маленькую кучу, чтобы память выделялась в пределах этой маленькой кучи только?

    Выделяете блок памяти любым из известных вам способов, декларируете функции а-ля myalloc и myfree, и реализуете один из алгоритмов управления свободным пространством в куче (например, двоичного разбиения).

    В C++ можно переопределить операторы new и delete.
    Ответ написан
    8 комментариев
  • Нужен ли сейчас Си?

    Nipheris
    @Nipheris Куратор тега C++
    Си как язык и экосистема, безусловно, нужны много где. Вопрос в том, нужны ли ВЫ этой экосистеме. Любой специались ценен не только знанием языка, но еще и знанием экосистемы и, самое главное, умением решать задачи, где вышеуказанный язык даёт наибольшую эффектиновсть с точки зрения бизнеса.
    Мало кому сегодня нужен человек, знающий PHP, но не знающий ничего о веб-разработке. С Си (да и с C++) то же самое. Чтобы вам давали те задачи, для решения которых имеет смысл использовать именно Си, вам нужно расти как специалист и в других областях. Например, хорошо разбираться в структурах данных. В управлении памятью. В машинной арифметике.
    Сравните например, человека, который просто знает, что в языке Си есть тип float, и человека, которому известно, что в Сишный float не запишешь значение 0.13, не потеряв в точности. А также человека, который понимает, почему точность теряется. И еще человека, который знает, что можно предпринять, если все-таки нужно как-то оперировать с десятичными дробями без потери точности.

    Этот ответ должен вас мотивировать на рост как IT-специалиста в целом, уделяющего дополнительное внимание принципам работы вычислительной техники и различным низкоуровневым вещам.
    Ответ написан
    2 комментария
  • Какую книгу лучше взять для изучение программы visual studio?

    Nipheris
    @Nipheris Куратор тега C++
    Для "изучения" вещей, таких как IDE, в которых и изучать то нечего, есть официальная документация. Официальная документация к продуктам Microsoft, имеющих отношение к разработке ПО (VS, TFS, библиотеки и прочее), находится на специальном портале, называемом Microsoft Developer Network (MSDN).
    Ответ написан
    Комментировать
  • Как преобразовать 1 байт и 0,5 байта в 1,5 байта(Более подробно в описании)?

    Nipheris
    @Nipheris Куратор тега C++
    Я предполагаю нужно выделить 2 байта и записать туда их как-то.

    Вам нужно считать эти два байта как единое целое (например, если вы используете потики, то считать нужно в short int), либо, если это невозможно, то тогда считать байты по отдельности и объединить их в int16_t, как советует Denis Zagayevskiy . И в том и в другом случае вам нужно понимать, что такое порядок байт в записи числа. Когда вы поймете, что такое порядок байт, то поймете, в чем суть вашего вопроса. Следить за ним нужно, т.к. в файле этот порядок байт может быть одним (и он определяется форматом файла), а на вашей машине он, в теории может быть другим, и вам нужно это понимать, когда вы будете склеивать вам int16_t. Если вы не будете его склеивать, а будете считывать сразу в int16_t, то вам нужно сверить порядок байт на вашей архитектуре и в формате файла.

    И да, числа в современной выч. технике:
    а) хранятся в двоичной системе счисления - т.е. все, что вы видите в дебаггере или в вашей программе - это целиком зависит от того, как функция преобразования числа в строку (которую вы потом видите) выбирает символы для записи числа. В большистве таких функций можно указывать систему счисления. Напишите сами такую функцию,чтобы понять, о чем речь;
    б) их размер в памяти/регистрах процессора выровнен на размер байта (как правило это 8 бит). Байт - это квант адресации и обработки данных, поэтому говорить, что число занимает 0.5 байта не вполне корректно с практической точки зрения, т.к. байт занять можно только целиком.

    Т.к. про 0.5 байт вы упомянули скорее по ошибке, я думаю битовые поля вам не нужны.
    Ответ написан
    1 комментарий
  • Как генерировать код из XML?

    Nipheris
    @Nipheris Куратор тега C++
    В xml(xsd) список некоторых элементов, из которых нужно сгенерировать много кода на C/C++, который руками писать (и править) долго, муторно и чревато опечатками.

    Ну тогда берите XSLT и сможете сгенерить все что захотите, хоть сказку. Ничего более конкретного посоветовать не могу.
    Ответ написан
    Комментировать