Showing posts with label C/Cpp. Show all posts
Showing posts with label C/Cpp. Show all posts

How to check variant type in C++

 C++ example:

#include <typeinfo>
#include <iostream>
int main() {
int nInt;
char cChar;
std::cout<<"nInt type = " << typeid(nInt).name() <<std::endl;
std::cout<<"cChar type = " << typeid(cChar).name() <<std::endl;
return 0;
}
if you define #include <typeinfo>, you can know type info of the variant.

How to build multi binaries through cmake.

Topic :

1. How to build multi binaries through cmake.
2. How to make multi binaries by preprocess.


RAII(Resource Acquisition Is Initialization)


Resource acquisition is initialization (RAII) is a programming idiom used in several object-oriented languages to describe a particular language behavior.

RAII (Resource Acquisition Is Initialization) is one of the famous design patterns.
The technique was developed for exception-safe resource management in C++ during 198489, primarily by Bjarne Stroustrup and Andrew Koenig.

RAII patterns are important techniques for preventing leakage in languages such as C++ that require developers to directly manage resources.


The following C++11 example demonstrates usage of RAII for file access and mutex locking:

#include <fstream>
#include <iostream>
#include <mutex>
#include <stdexcept>
#include <string>
void WriteToFile(const std::string& message) {
  // |mutex| is to protect access to |file| (which is shared across threads).
  static std::mutex mutex;
// Lock |mutex| before accessing |file|.
  std::lock_guard<std::mutex> lock(mutex);
// Try to open file.
  std::ofstream file("example.txt");
  if (!file.is_open()) {
    throw std::runtime_error("unable to open file");
  }
// Write |message| to |file|.
  file << message << std::endl;
// |file| will be closed first when leaving scope (regardless of exception)
  // mutex will be unlocked second (from lock destructor) when leaving scope
  // (regardless of exception).
}



<Ref : https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization>

#RAII #Resource Acquisition Is Initialization #C++ #mutex #Memory leakage #std::auto_ptr

Signal Handling Example (linux C/C++)


Signal Handling Example (linux C/C++)

#include <iostream>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <fstream>

class TestClass{
public:
    static void handle_signal(int signal);
};
void TestClass::handle_signal(int signal) {
    //char *signalName;
    std::string signalName = "";
    sigset_t pending;
    switch(signal) {
        case SIGHUP:
            signalName = "SIGHUP";
            break;
        case SIGINT:
            signalName = "SIGINT";
            break;
        case SIGTERM:
            signalName = "SIGTERM";
            break;
        case SIGQUIT:
            signalName = "SIGQUIT";
            break;
        case SIGKILL:
            signalName = "SIGKILL";
            break;
        default:
            printf("Caught unknown signal: %d\n", signal);
            return;
    }
    //실행하고 싶은 함수        
    std::ofstream outFile("./output.txt"std::ios::app);
    printf("Linux signal occurred. signal[%d] : name[%s]\n", signal, signalName.c_str());
    std::string str(std::string("Linux signal occurred. signal[") + std::to_string(signal) + "] signal Name["std::string(signalName) + "]");
    outFile << str << std::endl;
    outFile.close();
    //exit(0);
}
int main(int argcchar* arv[]) {
    TestClass *A = new TestClass();
    struct sigaction signalhandler;
    //stack_t sigstk; //for seg.fault
    //if ((sigstk.ss_sp = (char *)//malloc(SIGSTKSZ*2))==NULL) {
    //fprintf(stderr, "can't alloc alt stack\n");
    //}
    //sigstk.ss_size = SIGSTKSZ*2;
    //sigstk.ss_flags = 0;
    //if(sigaltstack(&sigstk, (stack_t *) 0) < 0) {
    //perror("sigaltstack");
    //}
    signalhandler.sa_handler = &TestClass::handle_signal;
    sigemptyset(&signalhandler.sa_mask);
    signalhandler.sa_flags = SA_RESETHAND | SA_ONSTACK;
    sigaction(SIGSEGV, &signalhandler,NULL);
    sigaction(SIGHUP, &signalhandler,NULL);
    sigaction(SIGINT, &signalhandler,NULL);
    sigaction(SIGTERM, &signalhandler,NULL);
    sigaction(SIGQUIT, &signalhandler,NULL);
    sigaction(SIGKILL, &signalhandler,NULL);

    while(1) {
    }

    return 1;
}



#Signal #Signal Handling #Signal Handler #C #C++ #Linux #Embedded

pure virtual function call (C/C++)

armv7 toolchain Error

error message:
pure virtual function call

solve:
1. Occurs when calling a virtual function from a constructor or destructor.
2. Compiler option did not write -march==armv7-a.

example :
arm-linux-gnueabi-g++ -fno-omit-frame-pointer -march=armv7-a -funwind-tables

#toolchain #embedded #C #C++

Terminate called out an active extension / Aborted (C/C++)


You can build it, but when you run it,
Execute and die when an error occurs.

Error Message:
Terminate called out an active extension
Aborted


Problem
Occurs when coding using "std::thread"

Cause / Solution
When coding using "std::thread", it is caused by not inserting "join"


Example Code:
class TEST {
TEST();
~TEST();

void init();
void end();
std::shared_ptr<std::thread> th = nullptr;

void exec(){}
}

void TEST::init() {
    th = std::make_shared<std::thread>(&TEST::exec , this);
}
void TEST::end() {
if(th != nullptr) {
th->join();
th = nullptr;
}
}

int main() {
Test *t = new TEST();
t->init();

if( t != nullptr ) {
delete t;
t = nullptr;
}
// If this program ends here, an error will occur.

//add code
t->end();
if( t != nullptr ) {
delete t;
t = nullptr;
}
//solved code !
}




#linux #embedded #C #C++ #debug #error #thread #join

wstring to string / string to wstring / utf16 to utf8 / utf8 to utf16(C/C++)

wstring to string / string to wstring

for utf16 parsing error


#include <locale>
#include <codecvt>
#include <string>

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string Str_UTF8 = converter.to_bytes(utf16String);
std::wstring wideString_UTF16 = converter.from_bytes(utf8String);

For use, you should modify the bold writing.

#utf16 #utf8 #wstring #string #C #C++ #Embedded #Linux

Function execution time Example. (C++)


std::chrono::system_clock::time_point start = std::chrono::system_clock::now();

myFunc();

std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;

std::cout << "The time taken to perform the function myFunc()  : " << sec.count() << " seconds" << std::endl;


Create Thread Class Example (C++)


The class "std :: thread" exists but has been created for fun.



ThreadClass.h

#pragma once
#include <iostream>
#include <windows.h>

class ThreadClass
{
public:
ThreadClass();
~ThreadClass();

void start();
void stop();
bool isRun();

static DWORD __stdcall run_(void* p);

virtual void run() = 0;

protected:
bool threadRunFlag;
HANDLE m_Thread;
};




ThreadClass.cpp


#include "ThreadClass.h"


//
//\brief constructor,
//\param
//\return
//
ThreadClass::ThreadClass()
{
this->threadRunFlag = false;
}


//
//\brief destructor
//\param
//\return
//
ThreadClass::~ThreadClass()
{
if (this->isRun()) {
this->stop();
}
}

//
//\brief  thread start
//\param
//\return
//
void ThreadClass::start()
{
m_Thread = CreateThread(0, 0, run_, (void*)this, 0, 0);
}

///
///\brief thread end
///\param
///\return
///
void ThreadClass::stop()
{
this->threadRunFlag = false;
// to be...
}

//
//\brief thread status
//\param
//\return
//
bool ThreadClass::isRun()
{
return this->threadRunFlag;
}

//
//\brief thread run
//\param
//\return
//
DWORD __stdcall ThreadClass::run_(void * p)
{
ThreadClass* const THISCLASS = static_cast<ThreadClass*>(p);
THISCLASS->threadRunFlag = true;
THISCLASS->run();

return 0;
}

if the source don't exist "default" in "Switch case" syntax ?

if the source don't exist "default" in "Switch case" syntax ?

this isn't error, but warning.

for example,

int test = 10;

printf("here 1");

switch (test) {
case 1:
break;
}

printf("here 2");


result console
here 1
here 2

you can show in this case, don't need to "default".
i think the compiler does write automatically.
but, this is warning.
i recommend to write "default".


little endianness, big endianness

엔디언(Endianness)은 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며, 바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 한다.
엔디언은 보통 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있으며, 두 경우에 속하지 않거나 둘을 모두 지원하는 것을 미들 엔디언(Middle-endian)이라 부르기도 한다.

바이트 순서는 크게 빅 엔디언과 리틀 엔디언으로 나눌 수 있다. 빅 엔디언은 사람이 숫자를 쓰는 방법과 같이 큰 단위의 바이트가 앞에 오는 방법이고, 리틀 엔디언은 반대로 작은 단위의 바이트가 앞에 오는 방법이다. PDP-11과 같은 몇몇 아키텍처는 2바이트 단위와 1바이트 단위로 서로 다른 순서를 사용하기도 하는데 이들을 미들 엔디언이라 부른다. 다음은 이런 방법들을 비교한 것이다.
종류0x1234의 표현0x12345678의 표현
빅 엔디언12 3412 34 56 78
리틀 엔디언34 1278 56 34 12
미들 엔디언-34 12 78 56
또는
56 78 12 34
두 방법 중 어느 한 쪽이 다른 쪽과 비교해 압도적으로 좋거나 나쁘지는 않다고 알려져 있으며, 두 방법은 서로 다른 여러 아키텍처에서 서로 공존하고 있다. 그러나 x86 아키텍처가 리틀 엔디언을 쓰기 때문에, 오늘날 x86 아키텍처를 사용하는 대부분의 데스크톱 컴퓨터는 리틀 엔디언을 쓰며 이를 ‘인텔 포맷’이라 한다. 거꾸로 네트워크에서는 주소를 빅 엔디언으로 쓰는데, 역사적으로 라우팅이 전화를 거는 식으로 접두 부호로 이루어졌기 때문이다. 이의 영향으로 많은 프로토콜과 몇몇 파일 포맷이 빅 엔디언을 사용하고 있다. 모토로라 프로세서들은 일반적으로 빅 엔디언을 사용하며, ARM 프로세서들은 성능 향상을 위해 빅 엔디언과 리틀 엔디언을 선택할 수 있도록 되어 있다.

빅 엔디언은 소프트웨어의 디버그를 편하게 해 주는 경향이 있다. 사람이 숫자를 읽고 쓰는 방법과 같기 때문에 디버깅 과정에서 메모리의 값을 보기 편한데, 예를 들어 0x59654148은 빅 엔디언으로 59 65 41 48로 표현된다.
반대로 리틀 엔디언은 메모리에 저장된 값의 하위 바이트들만 사용할 때 별도의 계산이 필요 없다는 장점이 있다. 예를 들어, 32비트 숫자인 0x2A는 리틀 엔디언으로 표현하면 2A 00 00 00이 되는데, 이 표현에서 앞의 두 바이트 또는 한 바이트만 떼어 내면 하위 16비트 또는 8비트를 바로 얻을 수 있다. 반면 32비트 빅 엔디언 환경에서는 하위 16비트나 8비트 값을 얻기 위해서는 변수 주소에 2바이트 또는 3바이트를 더해야 한다. 보통 변수의 첫 바이트를 그 변수의 주소로 삼기 때문에 이런 성질은 종종 프로그래밍을 편하게 하는 반면, 리틀 엔디언 환경의 프로그래머가 빅 엔디언 환경에서 종종 실수를 일으키는 한 이유이기도 하다.

reference: https://ko.wikipedia.org/wiki/%EC%97%94%EB%94%94%EC%96%B8
reference: https://en.wikipedia.org/wiki/Endianness

how to initialize array(C / C++)


case 1, 2, 3
int array[5] = { 0 };  VS int array[5] = { 0, };
and
memset(array, 0, 5);

case 1, 
int array[5] = { 0 };
=  array[0] = 0
    array[1] ~ array[4] = not initialized ? NO!
=  array[0] ~ array[4] = 0  Of Course, OK!

case 2,
int array[5] = { 0, };
=  array[0] ~ array[4] = 0  OK!

result :

int array[5]={0,1,2};
and
int array[5]={0,1,2,};

The elements array[4] and array[5] are automatically initialized to 0 in this case. 

the compiler take care of the rest(zero-initialize).


case 3,
memset(array, 0 , 5);

I don't recommend this case.
because you need to #include a special header(#include <cstring>).
and this case, all element is initialized to number 0.
so, you can't set to the value of 1 element and 2, ... .

snprintf : zero-length gnu_prntf format string

snprintf(str, sizeof(""), "")
--> sprintf(str, "");

zero-length gnu_printf format string

#C #C++ #sprintf #zero-length #gnu_printf #format string

Structure vs Class Only different !

Structure vs Class

only different: base access modifier

Structure is Public.
Class is Private.


printf % type

%c/%C  char
%s  string 
%p  pointer value hexadecimal number
%d/%i  signed decimal number
%u  unsigned decimal number
%f/%F  float
%e/%E  ?(real number exponent ?)
%g/%G  according to size, if size is small, %f/ if big is, %e
%x/%X  hexadecimal number
%o octal number
%n  line feed

C Language - extern ?

Extern
- The extern keyword declares a variable or function and specifies that it has external linkage.

C++ Shift operator(KO)

Shift operator- cout, cin 쓸때 앞이나 뒤에 붙이는 연산자
- 표준 라이브러리에 std라는 namespace에 cout이나 cin에 관련된 클래스(istream, ostream)
- C++에서는 쉬프트 연산자도 연산자 오버로딩이 가능


Shift operator overloading
-----------------------------
int main()
{
    VALUE val(2,3); 
    std::cout << val;
    return 0;
}


1. VALUE class show x and y value.
2. create val Object. after, std::cout print val .

Error : 
cout : - possible normal data type printing
         - impossible object of user type

-표준 std의 ostream 클래스에서도 쉬프트 연산에 대한 오버로딩이 정의 되어 있지 않음
따라서,  표준 라이브러리로 객체를 출력하는 일 불가능

-> Solution
overloading of member fucntion

cout is cout.operator

cout.operator<< (val)


val 객체 인자값을 받을 수 있도록 cout 객체에는 operator<< 연산자를 오버로딩 시키면 가능


class VALUE{  

private:  
    int iX;
    int iY;  
public:  
    VALUE(int x=0, int y=0):iX(x), iY(y){}  
    friend ostream& operator<<(ostream& os, const VALUE& val);  
};  
  
ostream& operator<<(ostream& os, const VALUE& val)  
{  
    os<<"["<<val.iX<<", "<<val.iY<<"]"<<endl;   

    return os;  
}  
  
int main(void)  
{  
    VALUE val(2, 3);  
    std::cout<<val;  
    return 0; 
}

member func overloading : CHANGE std::cout<<val; to operator(std::cout, VALUE); 

NO logical problem. 

How to use #ifdef to C/C++

example
int testfunc(int x, int y)
{
#ifdef  _DEBUG
      printf("x=%d, Y=%d", x,y);  // if x=1, y =2 
#endif
   return  (x * Y) ;
}

if debug mode
#define _DEBUG "DEBUG"

print x=1, Y=2
after return


if release mode,
not print
return

C/C++ Data type byte range


data type

data type  byte

unsigned long       DWORD
int                        BOOL;
unsigned char       BYTE;
unsigned short      WORD;
unsigned int          UINT;

char            1 byte -128 ~ 127
unsigned char 1 byte 0 ~ 255

int8                 1 byte -128 ~ 127

int16         2 byte -32,768 to 32,767

unsigned int 2 byte -32,768 to 32,767

(signed) short (int)        2 byte -32,768 to 32,767
unsigned short (int)         2 byte 0 ~ 65,535

int32                        4 byte -2,147,483,648 ~ 2,147,483,647

(signed) int                4 byte -2,147,483,648 ~ 2,147,483,647
unsigned int                4 byte 0 ~ 4,294,967,295

(signed) long (int)        4 byte -2,147,483,648 ~ 2,147,483,647
unsigned long (ing)          4 byte -2,147,483,648 ~ 2,147,483,647
int64                        8 byte -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
float                                 4 byte 3.4E +/- 38 (7 digits)
double                        8 byte 1.7E +/- 308 (15 digits)
long double                8 byte 1.2E +/- 4932 (19 digits)


Apartment Buying Guide 2025: Shocking Red Flags You Should NEVER Ignore!

 🏙️ Apartment Buying Guide 2025: Shocking Red Flags You Should NEVER Ignore! 🚨 Are you thinking about buying an apartment in 2025? 🏢  It’...