<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[char * als char const *&amp;amp;]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich arbeite zurzeit an einer eigenen StringStream-Klasse und habe an einer Stelle das Problem, dass mein Code unsagbar hässlich ist, weil ich eine eigentlich harmlose Typumwandlung ohne const_cast nicht hinbekomme: Von 'char *' nach 'char const *&amp;'.</p>
<p>Hier ein vereinfachter Ausschnitt aus meinem Code:</p>
<pre><code class="language-cpp">void detectString( char const *&amp; a_begin, char const *&amp; a_end )
{
    while ( *a_begin == ' ' )
        ++a_begin;
    a_end = a_begin;
    while ( *a_end != ' ' )
        ++a_end;
}

class MyStringStream
{
    [...]

private:
    char * m_buffer;
    int    m_position;

    [...]

public:
    MyStringStream &amp; operator &gt;&gt; ( double &amp; a_dest )
    {
        char * begin = m_buffer + m_position;
        char * end;
        detectString( *const_cast&lt; char const ** &gt;( &amp;begin ), *const_cast&lt; char const ** &gt;( &amp;end ) );  // Furchtbar.

        char tempChar = *end;
        *end = 0;  // Nötig, da strtod bei langen (c)strings sehr langsam ist.
        a_dest = strtod( begin, 0 );
        *end = temp;

        m_position += ( end - begin );
    }

    [...]
};

int main( void )
{
    MyStringStream TestStream;
    double d;

    TestStream &lt;&lt; &quot;    4.5    &quot;;
    TestStream.Seek( 0 );
    TestStream &gt;&gt; d; // d ist jetzt 4.5
}
</code></pre>
<p>Gibt es irgendeine Möglichkeit, diese eine schreckliche Zeile schöner zu machen, ohne dass die Performance beeinträchtigt wird?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/295036/char-als-char-const-amp</link><generator>RSS for Node</generator><lastBuildDate>Sat, 15 Aug 2026 15:11:45 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/295036.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 05 Nov 2011 20:16:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sat, 05 Nov 2011 20:16:58 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich arbeite zurzeit an einer eigenen StringStream-Klasse und habe an einer Stelle das Problem, dass mein Code unsagbar hässlich ist, weil ich eine eigentlich harmlose Typumwandlung ohne const_cast nicht hinbekomme: Von 'char *' nach 'char const *&amp;'.</p>
<p>Hier ein vereinfachter Ausschnitt aus meinem Code:</p>
<pre><code class="language-cpp">void detectString( char const *&amp; a_begin, char const *&amp; a_end )
{
    while ( *a_begin == ' ' )
        ++a_begin;
    a_end = a_begin;
    while ( *a_end != ' ' )
        ++a_end;
}

class MyStringStream
{
    [...]

private:
    char * m_buffer;
    int    m_position;

    [...]

public:
    MyStringStream &amp; operator &gt;&gt; ( double &amp; a_dest )
    {
        char * begin = m_buffer + m_position;
        char * end;
        detectString( *const_cast&lt; char const ** &gt;( &amp;begin ), *const_cast&lt; char const ** &gt;( &amp;end ) );  // Furchtbar.

        char tempChar = *end;
        *end = 0;  // Nötig, da strtod bei langen (c)strings sehr langsam ist.
        a_dest = strtod( begin, 0 );
        *end = temp;

        m_position += ( end - begin );
    }

    [...]
};

int main( void )
{
    MyStringStream TestStream;
    double d;

    TestStream &lt;&lt; &quot;    4.5    &quot;;
    TestStream.Seek( 0 );
    TestStream &gt;&gt; d; // d ist jetzt 4.5
}
</code></pre>
<p>Gibt es irgendeine Möglichkeit, diese eine schreckliche Zeile schöner zu machen, ohne dass die Performance beeinträchtigt wird?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140855</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140855</guid><dc:creator><![CDATA[Baltram]]></dc:creator><pubDate>Sat, 05 Nov 2011 20:16:58 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sat, 05 Nov 2011 21:01:15 GMT]]></title><description><![CDATA[<p>strtod ist bei langen Strings langsam?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140872</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140872</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sat, 05 Nov 2011 21:01:15 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sat, 05 Nov 2011 22:32:06 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>strtod ist bei langen Strings langsam?</p>
</blockquote>
<p>Oh ja. (Zumindest in der MSVC++ 2005-Implementierung.)<br />
Vermutlich bestimmt strtod zu irgendeinem Zeitpunkt die Länge des Strings.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140894</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140894</guid><dc:creator><![CDATA[Baltram]]></dc:creator><pubDate>Sat, 05 Nov 2011 22:32:06 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 09:00:48 GMT]]></title><description><![CDATA[<p>Baltram schrieb:</p>
<blockquote>
<p>[...] habe an einer Stelle das Problem, dass mein Code unsagbar hässlich ist, weil ich eine eigentlich harmlose Typumwandlung ohne const_cast nicht hinbekomme: Von 'char *' nach 'char const *&amp;'.</p>
</blockquote>
<p>So eine Konvertierung ist nicht harmlos. Würde das ohne const_cast funktionieren, wäre es eine Lücke im const-System:</p>
<pre><code class="language-cpp">const char foo = 23;
char* ptr = 0;
char const* &amp;ref = ptr; // (*)
ref = &amp;foo; // oops! ptr (ein zeiger auf nicht-const!) zeigt jetzt auch auf foo!!!
*ptr = 42;  // oops! Der Versuch, foo zu ändern ruft undefiniertes Verhalten hervor!
</code></pre>
<p>Deswegen akzeptiert der Compiler so etwas wie in Zeile 3 (*) nicht ohne const_cast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140948</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140948</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sun, 06 Nov 2011 09:00:48 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 07:44:46 GMT]]></title><description><![CDATA[<p>Also deine Antwort verstehe ich jetzt nicht, krümelkacker. Er will doch const hinzucasten, wenn ich das richtig sehe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140952</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140952</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Sun, 06 Nov 2011 07:44:46 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 09:30:45 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Also deine Antwort verstehe ich jetzt nicht, krümelkacker. Er will doch const hinzucasten, wenn ich das richtig sehe.</p>
</blockquote>
<p>Das const bezieht sich aber nur auf den &quot;Pointee&quot; (auf das gezeigte), nicht aber auf den Zeiger selbst. Den Zeiger könnte man also noch über die Referenz ändern und damit so etwas wie einen versteckten const-cast durchführen. Ich finde das Beispiel einleuchtend. Was verstehst Du daran nicht?</p>
<p>Hier nochmal quasi das Gleiche mit Zeigern:</p>
<pre><code class="language-cpp">char * * p = ...;
char       * const * q = p; // OK
char const *       * r = p; // Fehler! (da &quot;const-Lücke&quot;)
char const * const * z = p; // OK (hier kann nichts schief gehen)
</code></pre>
<p>Würde bei 'r' der Compiler nicht streiken, könnte man damit const-Correctness ohne const_cast umgehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140958</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140958</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sun, 06 Nov 2011 09:30:45 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 09:40:56 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Hier nochmal quasi das Gleiche mit Zeigern:</p>
<pre><code class="language-cpp">char * * p = ...;
char       * const * q = p; // OK
char const *       * r = p; // Fehler! (da &quot;const-Lücke&quot;)
char const * const * z = p; // OK (hier kann nichts schief gehen)
</code></pre>
<p>Würde bei 'r' der Compiler nicht streiken, könnte man damit const-Correctness ohne const_cast umgehen.</p>
</blockquote>
<p>Ich versteh es auch nicht. Was kann man da umgehen? An &quot;char * * p&quot; ist doch garnichts const?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140966</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140966</guid><dc:creator><![CDATA[wert56zui]]></dc:creator><pubDate>Sun, 06 Nov 2011 09:40:56 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 10:04:54 GMT]]></title><description><![CDATA[<p>Noch etwas: das</p>
<pre><code class="language-cpp">char tempChar = *end;
        *end = 0;  // Der Deferenzierungsoperator muss weg
</code></pre>
<p>geht nicht, da <code>end</code> nicht auf eine gültige Adresse zeigt. Die Folge der Dereferenzierung eines nicht initialisierten Zeigers könnte alles Mögliche sein. Welchen Compiler verwendest du? Normalerweise müsste er einen Run-time Check Error werfen.</p>
<p>Edit: oh, habe übersehen, dass es VS05 ist. Der müsste aber solche Checks machen..</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140972</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140972</guid><dc:creator><![CDATA[*Rewind*]]></dc:creator><pubDate>Sun, 06 Nov 2011 10:04:54 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 10:43:00 GMT]]></title><description><![CDATA[<p>[Rewind] schrieb:</p>
<blockquote>
<p>Noch etwas: das</p>
<pre><code class="language-cpp">char tempChar = *end;
        *end = 0;  // Der Deferenzierungsoperator muss weg
</code></pre>
<p>geht nicht, da <code>end</code> nicht auf eine gültige Adresse zeigt. Die Folge der Dereferenzierung eines nicht initialisierten Zeigers könnte alles Mögliche sein. Welchen Compiler verwendest du? Normalerweise müsste er einen Run-time Check Error werfen.</p>
<p>Edit: oh, habe übersehen, dass es VS05 ist. Der müsste aber solche Checks machen..</p>
</blockquote>
<p>Quatsch, natürlich soll end hier auf eine gültige Adresse zeigen. (Auch wenn das nicht garantiert ist, da die detectString Funktion überhaupt nicht auf das Ende des Strings achtet.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140983</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140983</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sun, 06 Nov 2011 10:43:00 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 10:52:29 GMT]]></title><description><![CDATA[<p>Jetzt sehe ich auch, dass es davor durch die Funktion geändert wird. Ich nehme es zurück.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140988</guid><dc:creator><![CDATA[*Rewind*]]></dc:creator><pubDate>Sun, 06 Nov 2011 10:52:29 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 11:04:02 GMT]]></title><description><![CDATA[<p>Ich verstehs immer noch nicht. Wenn ich ein const hinzufüge, kann doch nichts schiefgehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140997</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140997</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Sun, 06 Nov 2011 11:04:02 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 11:52:47 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>(Auch wenn das nicht garantiert ist, da die detectString Funktion überhaupt nicht auf das Ende des Strings achtet.)</p>
</blockquote>
<p>&quot;Original&quot; achtet sie auf alle white-space characters und auf 0, hab's nur vereinfacht für hier.</p>
<p>314159265358979 schrieb:</p>
<blockquote>
<p>Ich verstehs immer noch nicht. Wenn ich ein const hinzufüge, kann doch nichts schiefgehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
</blockquote>
<p>Hier füge ich const hinzu und es geht was schief:</p>
<pre><code class="language-cpp">void setzeGleich( char const *&amp; a, char const * b )
{
    a = b;
}

int main()
{
    char const text[] = &quot;Unveränderbar&quot;;

    char * textPtr;
    setzeGleich( textPtr, text );  // Geht nicht, obwohl &quot;nur&quot; const bei 'textPtr' hinzugefügt wird.

    textPtr[ 0 ] = ' ';
    textPtr[ 1 ] = ' ';

    // 'text' ist jetzt &quot;  veränderbar&quot;.
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2141028</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141028</guid><dc:creator><![CDATA[Baltram]]></dc:creator><pubDate>Sun, 06 Nov 2011 11:52:47 GMT</pubDate></item><item><title><![CDATA[Reply to char * als char const *&amp;amp; on Sun, 06 Nov 2011 12:12:04 GMT]]></title><description><![CDATA[<p>wert56zui schrieb:</p>
<blockquote>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Hier nochmal quasi das Gleiche mit Zeigern:</p>
<pre><code class="language-cpp">char * * p = ...;
char       * const * q = p; // OK
char const *       * r = p; // Fehler! (da &quot;const-Lücke&quot;)
char const * const * z = p; // OK (hier kann nichts schief gehen)
</code></pre>
<p>Würde bei 'r' der Compiler nicht streiken, könnte man damit const-Correctness ohne const_cast umgehen.</p>
</blockquote>
<p>Ich versteh es auch nicht. Was kann man da umgehen? An &quot;char * * p&quot; ist doch garnichts const?</p>
</blockquote>
<p>Das Beispiel soll auch nur zeigen, welche Konvertierungen von C++ erlaubt werden und welche nicht.</p>
<p>314159265358979 schrieb:</p>
<blockquote>
<p>Ich verstehs immer noch nicht. Wenn ich ein const hinzufüge, kann doch nichts schiefgehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
</blockquote>
<p>Wenn Du es einfach <strong>irgendwo</strong> hinzufügen könntest, ja. Da könnte dann was schiefgehen.</p>
<p>Wäre die Stelle mit 'r' erlaubt, könnte man ohne const_cast folgendes machen:</p>
<pre><code>char * z = 0;
char const * * r = &amp;z;
const char k = 23;
*r = &amp;k;  // Upps! z (vom Typ [b]char*[/b]) zeigt jetzt auf k (vom Typ [b]const char[/b])
          // Und das passierte ohne const_cast !!!
</code></pre>
<p>T** -&gt; T const** ist deswegen nicht erlaubt.<br />
T** -&gt; T const*const* ist aber erlaubt. (hier kann nichts schief gehen)<br />
T** -&gt; T*const* auch. (hier kann nichts schief gehen)</p>
<p>Das Problem des Threaderstellers ist genau das Gleiche mit 'ner Referenz auf oberster Ebene. Und dazu hatte ich auch schon ein Beispiel gezeigt.</p>
<p>Vielleicht muss ich noch deutlicher werden. Wenn man einfach <strong>irgendwo</strong> ein const hinzufügen dürfte, bräuchten wir kein const_cast mehr, denn dann könnten wir uns const_cast einfach selbst bauen:</p>
<pre><code class="language-cpp">template&lt;class T&gt;
T* mach_weg_dat_const(T const* param)
{
  T* q;
  const T** r = &amp;q; // &lt;-- gut, dass das hier nicht wirklich kompiliert!
  *r = param;
  // q zeigt auf *param aber das const ist plötzlich weg!!!
  return q;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2141032</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2141032</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sun, 06 Nov 2011 12:12:04 GMT</pubDate></item></channel></rss>