В чем принципиальное отличие ссылки от указателя в С++? Какие ограничения есть у первых, а какие у вторых?
Вот некоторые из отличий::
nullptr
:void f(int* num, int& num2)
{
if(num != nullptr) // if nullptr ignored algorithm
{
}
// can't check num2 on need to use or not
}
const
#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
const int v = 10;
//int& const r = v; // Ошибка
const int& r = v;
enum
{
is_const = std::is_const<decltype(r)>::value
};
if(!is_const)
std::cout << "const int& r is not const\n";
else
std::cout << "const int& r is const\n";
}
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
Напомню самую основную инфо по корутинам:
co_return
. Оно позволяет вернуть значение из корутины в вызывающий код.co_await
. Оно приостанавливает выполнение текущей корутины и передает управление вызывающему коду. Когда результат работы другой корутины готов, выполнение текущей корутины возобновляется.std::coroutine_handle
. Она принимает указатель на функцию-корутину и возвращает объект класса std::coroutine_handle
.Ну а в этой статье ты найдёшь подробное описание разных нюансов и подводных камней, в процессе автор пишет асинхронный веб-клиент
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Intel x86-simd-sort 5.0
, в которой представлен новый API для сортировки пользовательских объектов C++ с помощью object_qsort
.Согласно тестам разработчиков проекта, новая поддержка сортировки пользовательских объектов C++ может быть в 4-5 раз быстрее, чем использование
std::sort
в системах AVX-512
, но в конечном итоге влияние на производительность будет варьироваться в зависимости от используемых задач.x86-simd-sort 5.0
добавлен новый API-интерфейс keyvalue_qsort
для сортировки массивов, представляющих пары «ключ-значение», и этот новый API тоже работает намного быстрее.x86-simd-sort 5.0
добавлена поддержка AVX2 для методов argosrt
и argselect
. Эти дополнения AVX2 уже вошли в исходную версию NumPy для NumPy 2.0, причем эта библиотека Python была одним из первых проектов, который добавил поддержку высокопроизводительной библиотеки Intel.@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
print()
на C++. Автор создал C++ версию
print()
для отладки, назвал её cpp_dump()
, и параллельно создал библиотеку cpp-dump
для управления цветов и другими параметрами отображения объектов. Функция
cpp_dump()
выводит разные объекты/переменные в строковом представлении, автоматически делает отступы для соответствия максимальной ширине строки.cpp_dump()
поддерживает различные другие типы, включая std::multimap
и std::complex
.Можно настраивать цвета отображаемых при помощи
cpp_dump()
объектов.@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
26 февраля 2024 года Белый дом США выпустил призыв переходить на языки программирования с безопасным доступом к памяти типа Rust. Бьёрн Страуструп, создатель языка C++, в комментарии для издания InfoWorld ответил на критику его творения.
Язык ассемблера и языки с низким уровнем абстракций по типу C и C++ поддерживают произвольную арифметику указателей с реальными адресами памяти без автоматической проверки границ, что допускает лёгкий «выстрел в ногу». Исторически сложилось, что на таких языках пишут низкоуровневые компоненты компьютерных систем: прошивки микроконтроллеров, операционные системы, критически важные и высоконагруженные приложения.
Аргументация Страструпа схожа с использованной ранее в ответе на призывы АНБ в 2022 году:
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
Представим, что вы разрабатываете приложение для калькулятора. В нём есть разные математические операции, такие как сложение, вычитание, умножение и деление. Однако, есть одна операция, которая не требует данных о конкретном экземпляре калькулятора для выполнения — это, например, операция вычисления квадратного корня. Для таких операций идеально подходят статические методы.
public class Calculator {
// Статический метод для вычисления квадратного корня
public static double squareRoot(double number) {
return Math.sqrt(number);
}
// Обычный метод для сложения
public double add(double number1, double number2) {
return number1 + number2;
}
}
Calculator
. Вы можете просто вызвать метод напрямую через имя класса:double result = Calculator.squareRoot(16); // Возвращает 4.0
static
Важно понимать, что статические переменные и методы хранятся в специальной области памяти (например, в
.data
или .bss
для C++), и их значения или состояния сохраняются на протяжении всего времени работы программы. Это делает их идеальными для хранения глобальных настроек или выполнения операций, которые не зависят от состояния объектов.— Static в C++ часто используется для определения глобальных переменных, статических членов класса и функций, ограниченных областью видимости файла. Это позволяет избежать конфликтов имен и обеспечивает более чистую структуру кода.
— Static в C# имеет более широкое применение, включая статические классы, которые не могут быть инстанциированы и содержат только статические члены. Это делает C# статические классы идеальными для создания утилит и вспомогательных методов.
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
#include <iostream>
#include <vector>
int main() {
std::vector<int> a{0,1,2,3,4,5};
int b = 0;
std::cout << a[b + 1] << std::endl; // подчеркивает 'b+1'
return 0;
}
возникает проблема:
Арифметическое переполнение: использование оператора "+" на байтовом значении 4 и приведение результата к байтовому значению 8. Приведите значение к более широкому типу перед вызовом оператора "+", чтобы избежать переполнения (io.2)
Почему возникает такое предупреждение?
b+1
имеет тип int
. Если предположить, что в b
будет максимальное значение, представимое типом int
, то получим UB. Решение: привести хотя бы один из операндов к 64-битному типу.
В общем, компилятор ругается здесь не на конкретные значения, а на типы, используемые в выражении.
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
C и C++ имеют свои собственные встроенные генераторы случайных чисел. Они реализованы в двух отдельных функциях, которые находятся в заголовочном файле
cstdlib
:srand()
устанавливает передаваемое пользователем значение в качестве стартового. srand()
следует вызывать только один раз — в начале программы (обычно в верхней части функции main()
)rand()
генерирует следующее случайное число в последовательности. Оно будет находиться в диапазоне от 0
до RAND_MAX
(константа в cstdlib
, значением которой является 32767
).Вот пример программы, в которой используются обе эти функции:
#include <iostream>
#include <cstdlib> // для функций rand() и srand()
int main()
{
srand(4541); // устанавливаем стартовое значение - 4 541
// Выводим 100 случайных чисел
for (int count=0; count < 100; ++count)
{
std::cout << rand() << "\t";
// Если вывели 5 чисел, то вставляем символ новой строки
if ((count+1) % 5 == 0)
std::cout << "\n";
}
}
// 14867 24680 8872 25432 21865
// ...
В C++ 11 добавили тонну нового функционала для генерации случайных чисел, включая алгоритм Вихрь Мерсенна, а также разные виды генераторов случайных чисел (например, равномерные, генератор Poisson и пр.). Доступ к ним осуществляется через подключение заголовочного файла
random
. Вот пример генерации случайных чисел в C++11 с использованием Вихря Мерсенна на картинке.
Вихрь Мерсенна генерирует случайные 32-битные целые числа
unsigned
(а не 15-битные целые числа, как в случае с rand()
), что позволяет использовать гораздо больший диапазон значений. Существует также версия (
std::mt19937_64
) для генерации 64-битных целых чисел unsigned
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
std::istream::eof()
- это признак плохого кода и что в частности неправильно писать:while (!input_stream.eof()) {
input_stream >> value;
process(value);
}
Что в этом коде не так? Как писать правильно?
std::istream::eof()
в том, что он выставляется только после выполнения какой-либо операции чтения. Поэтому происходит следующее:std::ifstream input_stream("empty_file.txt"); // Открываем пустой файл
if (!input_stream.eof()) { // eof() == false, т.к. мы еще ничего не читали
int value;
input_stream >> value; // Пытаемся читать число, а его там нет.
// Здесь eof() == true, но мы это не проверяем.
std::cout << value; // Выведется 0.
}
Так что если и вызывать
eof()
, то это надо делать после операции чтения.std::istream
умеют преобразовываться в bool
, а каждая операция чтения возвращает ссылку на std::istream
. Поэтому идиоматичный код выглядит следующим образом:while (input_stream >> value) {
process(value);
}
std::string str;
while (std::getline(input_stream, str)) { ... }
while (input_stream >> value1 >> value2) { ... }
Здесь если при чтении
value1
произойдет ошибка, то все последующие операции чтения (т.е. value2
) будут игнорироваться, по этому можно читать сразу несколько значений сразу, и уже потом проверять состояние std::istream
.@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
C и C++ имеют свои собственные встроенные генераторы случайных чисел. Они реализованы в двух отдельных функциях, которые находятся в заголовочном файле
cstdlib
:srand()
устанавливает передаваемое пользователем значение в качестве стартового. srand()
следует вызывать только один раз — в начале программы (обычно в верхней части функции main()
)rand()
генерирует следующее случайное число в последовательности. Оно будет находиться в диапазоне от 0
до RAND_MAX
(константа в cstdlib
, значением которой является 32767
).Вот пример программы, в которой используются обе эти функции:
#include <iostream>
#include <cstdlib> // для функций rand() и srand()
int main()
{
srand(4541); // устанавливаем стартовое значение - 4 541
// Выводим 100 случайных чисел
for (int count=0; count < 100; ++count)
{
std::cout << rand() << "\t";
// Если вывели 5 чисел, то вставляем символ новой строки
if ((count+1) % 5 == 0)
std::cout << "\n";
}
}
// 14867 24680 8872 25432 21865
// ...
В C++ 11 добавили тонну нового функционала для генерации случайных чисел, включая алгоритм Вихрь Мерсенна, а также разные виды генераторов случайных чисел (например, равномерные, генератор Poisson и пр.). Доступ к ним осуществляется через подключение заголовочного файла
random
. Вот пример генерации случайных чисел в C++11 с использованием Вихря Мерсенна на картинке.
Вихрь Мерсенна генерирует случайные 32-битные целые числа
unsigned
(а не 15-битные целые числа, как в случае с rand()
), что позволяет использовать гораздо больший диапазон значений. Существует также версия (
std::mt19937_64
) для генерации 64-битных целых чисел unsigned
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
acpp -o test -O3 test.cpp
позволяет создать бинарный файл, который будет работать на GPU от Intel, NVIDIA и AMD, что делает AdaptiveCpp единственным в мире компилятором SYCL, способным генерировать такие универсальные исполняемые файлы.AdaptiveCpp 24.02 также предлагает кэширование ядер на диске, автоматическую специализацию ядер во время выполнения и другие улучшения.
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
Полезная статья о том, что с C++ нужно быть поаккуратнее.
В статье освещается множество важных нюансов, в частности:
#define
free
delete
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
При использовании в C++ кода
while(!file.eof())
{
// Чтение из файла
}
получаются неприятности - лишняя считанная строка, например. Почему? Как правильно проверить, что достигнут конец файла?
В чём дело?
Лучше для этого использовать цикл
for
и в заголовке выполнять само чтение с проверкой:for(int n; file >> n; )
{
// Обработка считанного значения n
}
if (file.bad())
std::cout << "Ошибка ввода-вывода при чтении\n";
else if (file.eof())
std::cout << "Достигнут конец файла\n";
else if (file.fail())
std::cout << "Неверный формат данных\n";
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Это открытый проект парсера на базе LLVM/Clang для проверки кода C и C++ на предмет оценки его пригодности для работы внутри транспортных механизмов (автомобилей и прочего) и других критически важных для безопасности технических сред в рамках соответствия требованиям стандарта AUTOSAR (AUTOmotive Open System ARchitecture) C++14.
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
#include "include/cef_app.h"
int main(int argc, char* argv[]) {
CefMainArgs main_args(argc, argv);
CefSettings settings;
// выполняем инициализацию
CefInitialize(main_args, settings, nullptr, nullptr);
// создаем окно с UI
CefWindowInfo window_info;
CefBrowserHost::CreateBrowser(window_info, new SimpleHandler(), "file:///your_ui.html", CefBrowserSettings(), nullptr);
// цикл обработки сообщений
CefRunMessageLoop();
// Cef для окончания работы
CefShutdown();
}
Замените
"file:///your_ui.html"
на путь к вашему HTML-файлу. Вуаля! Ваш интерфейс на HTML/CSS уже встроен в приложение на C++.@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
Organic Maps призывает всех желающих принять участие в ежегодной программе Google Summer of Code 2024 (GSoC), в рамках которой контрибьюторы со всего мира участвуют в разработке программного обеспечения с открытым исходным кодом под руководством опытных наставников из различных организаций.
Участвуйте в GSoC, пробуйте свои силы)
(большая часть проекта на C++, 76.1%)
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Обсуждаются типы данных в C++, для которых не нужна дополнительная синхронизация при конкуретном доступе.
Параллельно спикер рассказывает, как С++ помогает тонко оптимизировать lock-free разработку с помощью memory ordering.
Рекомендую, затрагивается много полезных для понимания вещей
@cpluspluc
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM