{"id":8,"date":"2006-10-24T19:08:24","date_gmt":"2006-10-24T18:08:24","guid":{"rendered":"http:\/\/slack.codemaniacs.com\/blog\/2006\/10\/24\/recovecos-oscuros-de-c-c99-y-c\/"},"modified":"2023-05-07T06:56:49","modified_gmt":"2023-05-07T05:56:49","slug":"recovecos-oscuros-de-c-c99-y-c","status":"publish","type":"post","link":"https:\/\/slack.codemaniacs.com\/blog\/2006\/10\/24\/recovecos-oscuros-de-c-c99-y-c\/","title":{"rendered":"Recovecos oscuros de C, C99 y C++"},"content":{"rendered":"<p>Advertencia: Post para coders. Puede producir dolor de cabeza. Tambi\u00e9n puede contener informaci\u00f3n horriblemente equivocada, en cuyo caso se ruegan correcciones en los comentarios.<br \/>\nHoy me he pasado un buen rato preguntandome por qu\u00e9 no funcionaba esto (recemos para que el WordPress no me destroce demasiado el codigo :P) :<\/p>\n<pre>#include &lt;cstdio&gt;\nint main() \n{\n    int i; float f=1.0f;\n    i = *reinterpret_cast&lt;float*&gt;(&amp;f);\n    printf(\"i = 0x%0x\\n\", i);\n    return 0;\n}\n<\/pre>\n<p>Compilando sin optimizaci\u00f3n funcionaba como se esperaba, y con optimizaci\u00f3n daba un resultado distinto. Al principio pens\u00e9 &#8220;un error del gcc, seguro&#8221;, pero me he puesto a buscar y resulta que <a href=\"http:\/\/gcc.gnu.org\/bugs.html\">no es un bug, sino una feature<\/a>. ISO C tiene reglas en contra del aliasing de punteros que dicen que acceder a una variable mediante un puntero de un tipo incompatible es ilegal, asi que al activar las optimizaciones asume que esas cosas no pasan y genera un resultado incorrecto. Una solucion t\u00ed\u00adpica es el clasico <em>hack<\/em> en el que se define una union de un int y un float, se escribe en un miembro y se lee en el otro, pero creo que el estandar dice que en este caso el resultado est\u00e1 definido por la implementaci\u00f3n. Mala cosa. Tambien he leido por ahi que una buena opcion es usar memcpy, hacer una copia de lo que sea a otra posicion de memoria y te olvidas del aliasing.<\/p>\n<p>Mas cositas. Programando en la uni el otro dia pensamos en lo bonito que seria disponer de tipos de tama\u00f1o fijo, como los uint8, int32, que todos hemos usado alguna vez. Pues bien, en C existen y en C++ no. Ahora alguien se puede preguntar &#8220;\u00bfpero c\u00f3mo? si C es un subconjunto de C++!&#8221;, pero esto no solo no es cierto, sino que desde la aparici\u00f3n de <a href=\"http:\/\/en.wikipedia.org\/wiki\/C99#C99\">C99<\/a> hay incluso m\u00e1s <a href=\"http:\/\/en.wikipedia.org\/wiki\/Compatibility_of_C_and_C%2B%2B\">diferencias<\/a> (el estandar de C++ es del 98). En este caso, C99 especifica una cabecera <a href=\"http:\/\/en.wikipedia.org\/wiki\/Stdint.h\">stdint.h<\/a> que define tipos con nombres como int8_t.<\/p>\n<p>Por ultimo, una curiosidad del FAQ de C++: <a href=\"http:\/\/www.parashift.com\/c++-faq-lite\/const-correctness.html#faq-18.17\">esta permitido hacer un cast de &#8220;Blah *&#8221; a &#8220;const Blah *&#8221;, pero no un cast de &#8220;Blah **&#8221; a &#8220;const Blah **&#8221;<\/a>.<\/p>\n<p>Y eso es todo por hoy. Si ten\u00e9is alguna historia similar que contar son bienvenidos los comentarios.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Advertencia: Post para coders. Puede producir dolor de cabeza. Tambi\u00e9n puede contener informaci\u00f3n horriblemente equivocada, en cuyo caso se ruegan correcciones en los comentarios. Hoy me he pasado un buen rato preguntandome por qu\u00e9 no funcionaba esto (recemos para que el WordPress no me destroce demasiado el codigo :P) : #include &lt;cstdio&gt; int main() { [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts\/8"}],"collection":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/comments?post=8"}],"version-history":[{"count":2,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts\/8\/revisions"}],"predecessor-version":[{"id":112,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts\/8\/revisions\/112"}],"wp:attachment":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/media?parent=8"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/categories?post=8"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/tags?post=8"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}