Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High level style of string manipulation in c language (IDFGH-10764) #11980

Closed
baldhead69 opened this issue Jul 31, 2023 · 15 comments
Closed

High level style of string manipulation in c language (IDFGH-10764) #11980

baldhead69 opened this issue Jul 31, 2023 · 15 comments
Assignees
Labels
Resolution: Won't Do This will not be worked on Status: Done Issue is done internally Type: Feature Request Feature request for IDF

Comments

@baldhead69
Copy link

Is your feature request related to a problem?

No response

Describe the solution you'd like.

I would like to suggest a better way to manipulate strings in c, ie, better and quickly way, mainly quickly way.
Something like a high level language like java for example, with several ready and easy to use methods to manipulate strings with static or dynamic memory allocation options.

This lib must be added in https://components.espressif.com/

Possible candidate:
I never used this lib, i find his suggestion on stackoverflow.

https://bstring.sourceforge.net/

Describe alternatives you've considered.

No response

Additional context.

No response

@baldhead69 baldhead69 added the Type: Feature Request Feature request for IDF label Jul 31, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label Jul 31, 2023
@github-actions github-actions bot changed the title High level style of string manipulation in c language High level style of string manipulation in c language (IDFGH-10764) Jul 31, 2023
@0xjakob
Copy link
Contributor

0xjakob commented Jul 31, 2023

You can use the strings library of the C++ standard library in ESP-IDF.

What particular problems do you encounter or what particular features would you like to have?

@0xjakob 0xjakob self-assigned this Jul 31, 2023
@baldhead69
Copy link
Author

But isn't the c++ library too heavy ?

And also not sure if i can mix c with c++, i think so, but....

@0xjakob
Copy link
Contributor

0xjakob commented Jul 31, 2023

But isn't the c++ library too heavy ?

Depends on what your requirements are. Hence me asking which problems you encounter. Have you tried using it on your project?

@baldhead69
Copy link
Author

baldhead69 commented Jul 31, 2023

No. I never used c++ on esp32.

Just to really learn and code faster.

It's not the first time I've run into this "problem".
Actually I came across a simple "problem" of concatenating text, in my case constant text, with any variable, int or float or whatever. I know I can use snprintf, but buffer memory allocation is usually static and also requires several lines of code.
I think there is asprintf too, but....

Something like that only for int:

esp_err concat_text_int( const char* text, int number, const char** str )
{
    if( text == null || str == null )
    {
        ESP_LOGI();
        return err_arg;
    }

    size_t size = snprintf( NULL, 0, "%s%d", text, number ) + 1;  // +1 null character terminator.
    if( size < 0 )
        return ESP_FAIL;

    *str = (char*) malloc( size  );
    
    if( *str == null )
        return err_no_mem;

    size = snprintf( *str, size, "%s%d", text, number );
    if( size < 0 )
    {
        free( *str );
        return ESP_FAIL;
    }

    return ESP_OK;
}

@0xjakob
Copy link
Contributor

0xjakob commented Jul 31, 2023

In std::string, append, operator+= and insert all allow string concatenation. std::to_string converts numeric data to a string. Your function could be reduced to:

std::string concat_text_int(const char* text, int number)
{
    if (text == nullptr) 
    {
        throw std::invalid_argument("text was null");
    }

    std::string str(text);
    str.append(std::to_string(number));
    return str;
}

Note that you need to enable exceptions for this, but this all works and compiles on an ESP32.

The rest of the C++ standard library should cover most of the day-to-day programming needs for strings and also has more advanced concepts for rather special cases.

And also not sure if i can mix c with c++, i think so, but....

You can, it's perfectly legal. You need to consider language linking and designated initializers, though.

@espressif-bot espressif-bot assigned 0xjakob and unassigned 0xjakob Aug 2, 2023
@baldhead69
Copy link
Author

In std::string, append, operator+= and insert all allow string concatenation. std::to_string converts numeric data to a string. Your function could be reduced to:

std::string concat_text_int(const char* text, int number)
{
    if (text == nullptr) 
    {
        throw std::invalid_argument("text was null");
    }

    std::string str(text);
    str.append(std::to_string(number));
    return str;
}

Note that you need to enable exceptions for this, but this all works and compiles on an ESP32.

The rest of the C++ standard library should cover most of the day-to-day programming needs for strings and also has more advanced concepts for rather special cases.

And also not sure if i can mix c with c++, i think so, but....

You can, it's perfectly legal. You need to consider language linking and designated initializers, though.

I think str is local variable, no ?

I think i need to allocate this memory using new operator.

@0xjakob
Copy link
Contributor

0xjakob commented Aug 9, 2023

str is a local variable, that's correct. But it will automatically be transferred to the caller on return, if that is your concern.

You don't need to manually allocate or de-allocate memory when using std::string. The library does that automatically (like in Java or other high-level languages).

@baldhead69
Copy link
Author

baldhead69 commented Aug 9, 2023

str is a local variable, that's correct. But it will automatically be transferred to the caller on return, if that is your concern.

You don't need to manually allocate or de-allocate memory when using std::string. The library does that automatically (like in Java or other high-level languages).

C++ doen't have garbage collector, right ?

And local variables no longer exist outside the function.

If std::string allocate memory implicitly, i need to deallocate later, i just don't know if it use free or delete for this.

@0xjakob
Copy link
Contributor

0xjakob commented Aug 11, 2023

C++ doen't have garbage collector, right ?

No, it does not. But it has automatic destruction, which ensures that all memory is deallocated without user interaction (if the type supports it, and std::string does). This is called RAII.

And local variables no longer exist outside the function.

Yes, but if they are returned, they are automatically transferred to calling function. Transfer can mean copying the object, moving it, or, if the compiler is able to optimize, constructing the local variable directly in the scope of the calling function. This all happens automatically for std::string and all its allocated memory, you do not need to decallocate it yourself.

Even if you are not programming in C++, it might be a good chance to consider switching to it, if just for the parts dealing with strings. The C++ standard library has several advantages for users as well as for us:

  • Many parts, like std::string, are build with automatic resource management which prevents errors, e.g. accidental memory leaks. This is impossible in C. Automatic resource management is also something that gives you a lot of convenience when dealing with strings (you asked for easy to use methods and quicker coding)
  • It is actively maintained and heavily tested
  • It comes with the upstream tool chain, which means we don't need to maintain it ourselves, giving us more time to fix bugs and improve other aspects of ESP-IDF.
  • It has more advanced concepts, e.g. std::string_view, which allows light-weight string wrappers around pre-defined memory (you asked for static memory allocation options as well)

If you cannot use C++ for whatever reason, nothing should stop you from integrating any C library you want. If something is indeed stopping you from doing that, please let us know. The component registry has also been opened recently, so anyone can add their components there.

@baldhead69
Copy link
Author

@0xjakob,

Very good explanation.

The below doubt is valid both for c and c++ :

If i pass a string dynamic allocated (by pointer) to another lib, like network lib for example, to send this message by wifi.

How to know the right time to release the resource ( here the dynamically allocated memory for the string ) ?

  • if the string is copied, there is no problem.
  • if the string is passed by pointer, the string could only be deallocated when the network lib had sent the message ( with this string ).

Thank's.

@0xjakob
Copy link
Contributor

0xjakob commented Aug 15, 2023

How to know the right time to release the resource?

If you pass a char pointer, it depends on the library you are using when you can release the underlying memory. But this is not something a string library can help you with.

@baldhead69
Copy link
Author

How to know the right time to release the resource?

If you pass a char pointer, it depends on the library you are using when you can release the underlying memory. But this is not something a string library can help you with.

Yes, i know.

In the case of websocket server, would you know how to inform me ?
Or does it depend on some setting ?

Complicated to know when release resource when dealing with network library.

Thank's.

@0xjakob
Copy link
Contributor

0xjakob commented Aug 17, 2023

In the case of websocket server, would you know how to inform me ?
Or does it depend on some setting ?

Still assuming that you pass char pointers, it again depends on the library. But if you stick to C, you have to manage your memory yourself. I'm afraid this is not something ESP-IDF can help you with, and it is not the purpose of ESP-IDF to manage a user's memory, either.

@0xjakob
Copy link
Contributor

0xjakob commented Oct 30, 2023

@baldhead69 If there are no other questions, could we close this issue?

@baldhead69
Copy link
Author

@0xjakob ,

Yes, i can close.

Could you help me open this below issue again, i don't know why it was closed

#11903

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: Won't Do This will not be worked on and removed Status: Opened Issue is new labels Nov 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Won't Do This will not be worked on Status: Done Issue is done internally Type: Feature Request Feature request for IDF
Projects
None yet
Development

No branches or pull requests

3 participants