char_traits::assign question

Jan 9, 2017 at 1:57pm
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 Jan 9, 2017 at 4:01pm
Jan 9, 2017 at 2:16pm
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 Jan 9, 2017 at 2:17pm
Jan 9, 2017 at 3:56pm
"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 Jan 9, 2017 at 3:57pm
Jan 9, 2017 at 4:16pm
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.