<?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[Adresse einer Referenz]]></title><description><![CDATA[<p>Gibt es einen Weg, an die Adresse einer Referenz zu kommen?<br />
Der Anwendungsfall ist etwa wie folgt:</p>
<pre><code class="language-cpp">// inline assembler inside
HRESULT exceptionGuardedCall (void (*func)(void), void* first_stack_param, void* last_stack_param);

template &lt;typename TR, typename T0, typename T1, ..., typename Tn&gt;
    TR theRealFunction (T0 p0, T1, p1, ..., Tn pn);

template &lt;typename T0, typename T1, ..., typename Tn&gt;
    HRESULT theFunctionWrapper (T0 p0, T1, p1, ..., Tn pn, TR&amp; pr)
{
    return exceptionGuardedCall ((void (*)(void)) theRealFunction, &amp;p0, &amp;pr);
}
</code></pre>
<p>Das funktioniert offensichtlich nur solange, wie T0 und TR keine Referenztypen sind. Wie könnte man in diesem Fall dennoch an die Adresse des Parameters kommen?</p>
<p>Es ist mir durchaus bewußt, daß ich mich etwas außerhalb des C++-Standards bewege, aber ich meine mich schwach daran erinnern zu können, daß Boost eine Lösung dafür bereithält, aber ich finde sie nicht. (Oder kann addressof() das?)</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/228730/adresse-einer-referenz</link><generator>RSS for Node</generator><lastBuildDate>Mon, 28 Sep 2026 10:24:13 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/228730.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 02 Dec 2008 10:31:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 10:31:30 GMT]]></title><description><![CDATA[<p>Gibt es einen Weg, an die Adresse einer Referenz zu kommen?<br />
Der Anwendungsfall ist etwa wie folgt:</p>
<pre><code class="language-cpp">// inline assembler inside
HRESULT exceptionGuardedCall (void (*func)(void), void* first_stack_param, void* last_stack_param);

template &lt;typename TR, typename T0, typename T1, ..., typename Tn&gt;
    TR theRealFunction (T0 p0, T1, p1, ..., Tn pn);

template &lt;typename T0, typename T1, ..., typename Tn&gt;
    HRESULT theFunctionWrapper (T0 p0, T1, p1, ..., Tn pn, TR&amp; pr)
{
    return exceptionGuardedCall ((void (*)(void)) theRealFunction, &amp;p0, &amp;pr);
}
</code></pre>
<p>Das funktioniert offensichtlich nur solange, wie T0 und TR keine Referenztypen sind. Wie könnte man in diesem Fall dennoch an die Adresse des Parameters kommen?</p>
<p>Es ist mir durchaus bewußt, daß ich mich etwas außerhalb des C++-Standards bewege, aber ich meine mich schwach daran erinnern zu können, daß Boost eine Lösung dafür bereithält, aber ich finde sie nicht. (Oder kann addressof() das?)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624195</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624195</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Tue, 02 Dec 2008 10:31:30 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 11:01:08 GMT]]></title><description><![CDATA[<p>Das hättest du aber auch etwas abstrahieren können. Wenn ich dich richtig verstehe, dann ist dein Problem das folgende:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void foo(T&amp; t)
{
}

int main()
{
  int x = 0;
  foo&lt;int&gt;(x); // geht
  foo&lt;int&amp;&gt;(x); // geht nicht

  return 0;
}
</code></pre>
<p>korrekt?</p>
<p>Dann musst du einfach die Referenz des Typen entfernen, das geht auch mit boost:</p>
<pre><code class="language-cpp">#include &lt;boost/type_traits/remove_reference.hpp&gt;

template&lt;typename T&gt;
void foo(typename boost::remove_reference&lt;T&gt;::type&amp; t)
{
}

int main()
{
  int x = 0;
  foo&lt;int&gt;(x); // geht
  foo&lt;int&amp;&gt;(x); // geht auch

  return 0;
}
</code></pre>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624220</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624220</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 02 Dec 2008 11:01:08 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 11:28:37 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Wenn ich dich richtig verstehe</p>
</blockquote>
<p>Leider nicht. Ich möchte die Adresse der Stack-Parameter an exceptionGuardedCall() übergeben, auch wenn diese Referenzen sind.</p>
<p>exceptionGuardedCall() sieht etwa so aus:</p>
<pre><code class="language-cpp">HRESULT exceptionGuardedCall (void (*func)(void), void* first_stack_param, void* last_stack_param)
{
    try
    {
        // some horrible assembly tricks to push first_stack_param through
        // last_stack_param onto the stack and jump to func
    }
    catch (std::exception&amp; e)
    {
        // set error info via CreateErrorInfo() and SetErrorInfo()
        return 0xA0020001;
    }
    catch (...)
    {
        // set error info via CreateErrorInfo() and SetErrorInfo()
        return 0xA0020002;
    }
}
</code></pre>
<p>(Wer Delphi kennt, sieht, daß ich versuche, den safecall-Mechanismus nachzubauen.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624230</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624230</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Tue, 02 Dec 2008 11:28:37 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 12:02:12 GMT]]></title><description><![CDATA[<p>Kann man denn überhaupt davon ausgehen, dass die Parameter alle auf dem Stack liegen? Oo</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624259</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624259</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 02 Dec 2008 12:02:12 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 12:24:42 GMT]]></title><description><![CDATA[<p>Decimad schrieb:</p>
<blockquote>
<p>Kann man denn überhaupt davon ausgehen, dass die Parameter alle auf dem Stack liegen? Oo</p>
</blockquote>
<p>Nein, kann man nicht. MSVC beherrscht zum Beispiel eine Optimierung namens &quot;custom calling conventions&quot;, bei der Parameter auch über ungenutzte Register übergeben werden können.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624265</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624265</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Tue, 02 Dec 2008 12:24:42 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 12:46:16 GMT]]></title><description><![CDATA[<p>Bei zumindest einigen Compilern dürfte eine Referenz ja als Zeiger übergeben werden. Dann ließe sich die Adresse auf dem Callstack ja aus der Adresse des nächsten Parameters ableiten (&amp;next-sizeof(void*) oder &amp;next+sizeof(void*), keine Ahnung wie das mit den Aufrufkonventionen ist).<br />
Primitiv etwa so:</p>
<pre><code class="language-cpp">void foo( int&amp; a, int b )
{
	int addr_b = (int)(&amp;b);
	int addr_a = addr_b - sizeof(void*);
}
</code></pre>
<p>Das doofe ist nur, wenn der nächste Parameter auch eine Referenz ist, oder aber der gefragte Parameter der letzte ist. Da könnte helfen, eine Dummy-Funktion mit irgendeinem non-ref-Parameter dahinter zu stellen, die die Adressen rückwärts wieder aufrollt:</p>
<pre><code class="language-cpp">template&lt;class T&gt;
struct SizeofParam
{
	enum
	{
		Size = sizeof( 
				boost::mpl::if_c&lt; boost::is_reference&lt;T&gt;::value,
				 void*,
				 T&gt;::type
		)
	};
};

template&lt;class T, class U&gt;
void dummy_foo( T a, U b, int c )
{
	void* addr_c = &amp;c;
	void* addr_b = (char*)addr_c - SizeofParam&lt;U&gt;::Size;
	void* addr_a = (char*)addr_b - SizeofParam&lt;T&gt;::Size;

	size_t frame = (char*)addr_c - (char*)addr_a;

	std::cout &lt;&lt; &quot;Stackframe von &quot; &lt;&lt; addr_a &lt;&lt; &quot; bis &quot; &lt;&lt; addr_c &lt;&lt; &quot;  (&quot; &lt;&lt; frame &lt;&lt; &quot;)\n&quot;;
}

template&lt;class T, class U&gt;
void foo1( T a, U b )
{
	dummy_foo&lt;T,U&gt;( a, b, 0 );
}

int main()
{
	double i = 5;
	foo1&lt;double&amp;,char&gt;( i, 20 );
}
</code></pre>
<p>edit: Ne, ist Unsinn. Kann so nicht funktionieren, da bei nem char-Parameter ja oft trotzdem ein int auf den Stack gepusht wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624276</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624276</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Tue, 02 Dec 2008 12:46:16 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 12:39:50 GMT]]></title><description><![CDATA[<p>Das fällt einem dann natürlich in den Debug-Builds bestimmt nicht auf <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624277</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624277</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 02 Dec 2008 12:39:50 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 12:53:50 GMT]]></title><description><![CDATA[<p>LordJaxom schrieb:</p>
<blockquote>
<p>MSVC beherrscht zum Beispiel eine Optimierung namens &quot;custom calling conventions&quot;, bei der Parameter auch über ungenutzte Register übergeben werden können.</p>
</blockquote>
<p>Darf er das überhaupt, wenn man sich die Adressen der Parameter holt? Bzw wie sehen die dann aus?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624285</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624285</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Tue, 02 Dec 2008 12:53:50 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 13:27:26 GMT]]></title><description><![CDATA[<p>Decimad schrieb:</p>
<blockquote>
<p>Kann man denn überhaupt davon ausgehen, dass die Parameter alle auf dem Stack liegen? Oo</p>
</blockquote>
<p>Ja, kann man, insbesondere, wenn theFunctionWrapper() im realen Einsatz kein Template mehr ist, sondern als virtual __stdcall-Methode deklariert wird. Als Template habe ich die Funktion oben notiert, damit ersichtlich ist, daß ich nicht eine spezifische, sondern eine allgemein anwendbare Lösung benötige, die damit zurechtkommt, daß ein Parameter _eventuell_ einen Referenzypen hat.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13210">@Badestrand</a>: dein Ansatz ist nicht schlecht, aber man kann ihn leider in genau dieser Hinsicht kaum verallgemeinern, was in meinem Falle leider notwendig wäre.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624317</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624317</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Tue, 02 Dec 2008 13:27:26 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 13:36:56 GMT]]></title><description><![CDATA[<p>Wo ich das grad lese:<br />
Bisher dachte ich,<br />
Adresse eines Objektes == Adresse einer Referenz auf das Objekt<br />
scheint aber nicht so zu sein, wenn ich das hier richtig nachvollziehe.<br />
Sonst müsste ja ein<br />
theFunction&lt;int&gt; für int und int&amp; gehen...<br />
oder bringe ich da was durcheinander?</p>
<p>mfg,<br />
ein verwirrter branleb <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/1624323</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624323</guid><dc:creator><![CDATA[branleb]]></dc:creator><pubDate>Tue, 02 Dec 2008 13:36:56 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 13:53:45 GMT]]></title><description><![CDATA[<p>Für was für Compiler soll das denn funktionieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624345</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624345</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Tue, 02 Dec 2008 13:53:45 GMT</pubDate></item><item><title><![CDATA[Reply to Adresse einer Referenz on Tue, 02 Dec 2008 14:00:15 GMT]]></title><description><![CDATA[<p>branleb schrieb:</p>
<blockquote>
<p>Adresse eines Objektes == Adresse einer Referenz auf das Objekt<br />
scheint aber nicht so zu sein, wenn ich das hier richtig nachvollziehe.</p>
</blockquote>
<p>Doch, aus semantischer Perspektive ist das so, d.h., wenn du den &amp;-Operator auf eine Referenz anwendest, bekommst du die Adresse des Objektes, auf das sie verweist.</p>
<p>Praktisch allerdings sind Referenzen zumindest dort, wo sie Teil einer konsistenten Schnittstelle sind, als Zeiger implementiert. Und mein Problem ist, daß C++ keine Möglichkeit bietet, an ihre Adresse zu kommen.</p>
<p>Die einzige Möglichkeit, die ich gerade sehe, wäre, die gewünschten Daten mithilfe einer Kombination aus dem Ansatz von Badestrand und dem direkten Zugriff auf den Base-Pointer zu erhalten:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
    struct ParameterSize
{
    enum { value = boost::is_reference &lt;T&gt;::value ? sizeof (void*) : sizeof (T) };
};
template &lt;typename T0, typename T1, ..., typename Tn&gt;
    HRESULT theFunctionWrapper (T0 p0, T1, p1, ..., Tn pn, TR&amp; pr)
{
    char* begin = (char*) _EBX + 8; // _EBX + 4 ist die Rücksprungadresse
    char* end   = begin
                + ParameterSize &lt;T0&gt;::value
                + ParameterSize &lt;T1&gt;::value
                + ...
                + ParameterSize &lt;Tn&gt;::value;
    return exceptionGuardedCall ((void (*)(void)) theRealFunction, begin, end);
}
</code></pre>
<p>Leider ist das außerordentlich häßlich. Aber was bleibt mir übrig <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<p>Badestrand schrieb:</p>
<blockquote>
<p>Für was für Compiler soll das denn funktionieren?</p>
</blockquote>
<p>Windows, x86, möglichst alle, mindestens BCC.</p>
<p>Grundsätzlich wird die Fallback-Variante meines Safecall-Wrappers unter allen Compilern funktionieren, jedoch für einigen Bloat sorgen (jede einzelne Funktion bekäme dann einen try/catch-Block). Das möchte ich eben für so viele Compiler wie möglich vermeiden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1624349</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1624349</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Tue, 02 Dec 2008 14:00:15 GMT</pubDate></item></channel></rss>