char_traits::assign question

I am looking into the <string> header and came along char_traits::assign on <http://www.cplusplus.com/reference/string/char_traits/assign/>
there the reference states, that there is no return value, but the definition is for two overloads:

1
2
3
4
5
//character (1)	
static void      assign (char_type& r, const char_type& c) noexcept;

//array (2)	
static char_type assign (char_type* p, site_t n, char_type c);

for the first function I understand the "no return value" although I don't understand why it is defined as static void and not just void.
on the second function overload where n characters of char_type are written from the beginning of a string (char_type*), there should be a return, which is defined as static char_type.
<http://en.cppreference.com/w/cpp/string/char_traits/assign> has a slightly different definition but adds the return for the second definition as p.

To try it out, I found an example on <http://www.tenouk.com/Module26a.html>
and rewrote it a bit for me to understand what I am doing and where what comes from:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <string> // for char_traits/assign
#include <iostream> //for cout/endl

//not using namespace std general call
//using namespace std;
//but calling each command specifically

int main()
{
  // char_traits, assign()
  char chr1 = 'P';
  const char chr2 = 'Q';  // defined as const because value doesn't change

  // assigning character from chr2 to chr1
  std::cout << "The initial characters (chr1, chr2) are: (" << chr1 << "," << chr2 << ")" << std::endl;
  std::cout << "Operation: assign(chr1, chr2)" << std::endl;
  std::char_traits<char>::assign(chr1, chr2);
  std::cout << "The new characters (chr1, chr2) are: (" << chr1 << ", " << chr2 << ")" << std::endl << std::endl;

  // assigning character values to initial part of a string
  //std::char_traits<char>::char_type* str1 = "Testing assign()";
  //changing the definition from ptr to array for the value! thx Cubbi!
  std::char_traits<char>::char_type str1[] = "Testing assign()";
  std::char_traits<char>::char_type* result;
  std::cout << "\nThe target string str1 is: " << str1 << std::endl;
  std::cout << "Operation: assign(str1, 5, \'#\')" << std::endl;
  result = std::char_traits<char>::assign(str1, 5, '#');  //<--- problem!
  std::cout << "The result = " << result << std::endl;    //<--- does not display
  std::cout << " and str1  = " << str1 << std::endl;      //<--- does not display

  return 0;
}


but the c++ shell (cpp.sh) as well as vs(2015) "crash" on the second part
while cpp.sh has the following for line 21:
warning: deprecated conversion from string constant to 'std::char_traits<char>::char_type* {aka char*}' [-Wwrite-strings]

and with standard input set to none, the crashing part spits out:
Error launching program (Segmentation fault)

Why am I getting a segfault, why is cpp.sh warning about a deprecated conversion, and can the second assign example part be brought to function correctly?
Last edited on
These are related:

RobiBue wrote:
why is cpp.sh warning about a deprecated conversion
"Testing assign()" is a string literal, which is an array of const char, you can't make a pointer to non-const char point at it without a cast. This was permitted, but deprecated in C++98 and C++03, it's not allowed in C++ since C++11.

RobiBue wrote:
Why am I getting a segfault

Because you're trying to *write* into "Testing assign()", which is an array of const char. Luckily, the compiler(s) you used placed it in a read-only data section and the write triggered a memory protection violation.

also
//array (2)
static char_type assign

that's an error: the return type is char_type*, not char_type, I'll report it.
Last edited on
"Testing assign()" is a string literal, which is an array of const char, you can't make a pointer to non-const char point at it without a cast.

ok, the character string "Testing assign()" is an array of const char (like: const char[]? What I don't understand, is how str1 would end up becoming a const.

And by asking that question I just answered myself...

The line
std::char_traits<char>::char_type* str1 = "Testing assign()";
creates a char_type pointer named str1 which is assigned the address of the const char array "Testing assign()".
If instead of a pointer I define str1 as an array, like:
std::char_traits<char>::char_type str1[] = "Testing assign()";
then the second part also works because I don't have a pointer pointing to the definition string, but a non-const string variable containing the value to work with (I use the word string here as char[] substitute).
Thank you Cubby!

Now there is only one more question: what is static void used for with the first definition, or why is it static void and not just plain void?
Last edited on
what is static void used for with the first definition, or why is it static void and not just plain void?

It's a static member function that returns void. "static" applies to the function name, not to the return type.
Topic archived. No new replies allowed.