jueves, 25 de octubre de 2012

Designated Initializers

"Inicializadores Designados" (espero que sea una traducción aceptable).
He buscado tanto acerca de este tema y son tan escasas las referencias que vale la pena publicar una.

En Ansi C tenía el siguiente problema:
Necesito una estructura (struct) con algunos de sus miembros constantes:

struct
{
    int valor;
    const int constante1;
    const int constante2;
} mi_estructura;


El estándar no permite la inicialización de los elementos de una estructura, osea, si quiero que mis constantes sean 4 y 6:

struct
{
    const int constante1 = 4;
    const int constante2 = 6;
    int valor;
} mi_estructura;

NO ESTA PERMITIDO


Buscando encontré la forma de inicializar los miembros de struct. Entonces para hacer lo anterior correctamente sería:

struct
{
    const int constante1;
    const int constante2;
    int valor;
} mi_estructura = { 4, 6 };

PERMITIDO


Listo, ya hay una forma de hacerlo. Pero, aun no me gusta. La lista depende del orden en que coloco las variables miembro de struct. ¿que tal si muevo "int valor" al principio de la lista? ¿o si agrego una nueva variable? ¿o quito alguna?. Cuando lo haga debo ser muy cuidadoso en rehacer la lista de inicialización para respetar el nuevo orden (cuando alguien mas le haga mantenimiento a tu código después de tiempo, es MUY deseable que esto quede claro).

La solución (que escasamente pude encontrar) los "inicializadores designados" ("designed initializers"). Había sido tan simple como etiquetar cada elemento de la lista de inicialización anterior (un estilo muy similar a "enum"):

struct
{
    const int constante1;
    const int constante2;
    int valor;
} mi_estructura = { .constante2 =6, .constante1=4 };

PERMITIDO


Ahora si está mucho mejor. Quien le de mantenimiento a mi código debe fijarse solo en que el elemento constante de la estructura tenga su inicializador en la lista. Ya no debe preocuparse del orden y ni de una posible asignación errónea de valores.
Aún me gustaría evitar la edición en dos lugares, pero parece que es lo mejor que el estándar del C puede dar.


viernes, 13 de abril de 2012

ubuntu temp

gracias a TeoBigusGeekus en http://ubuntuforums.org/showthread.php?t=1688948&page=2

A continuacion una transcripcion de su aporte:

1)Open flash video page (that you own of course) and let it load. Don't close the page.


2)Open terminal and give
code:
lsof | grep Flash

lsof: list open files
In my case (opera user) it gives
code:
operaplug 2840 teo 9u REG 8,8 6962837 392986 /tmp/FlashXXFfe85s (deleted)


Notice the 2nd (process id) and 4rth (file descriptor - without the letter) columns.


3)
code:
cp /proc/2840/fd/9 ~/Desktop/video

lunes, 6 de febrero de 2012

Repositorio local de ubuntu con archivos descargados

Esta entrada está dedicada a las PC con Ubuntu, sin conexión a internet pero que quieren usar el synaptics como si estuvieran conectados.

Hay muchas ayudas al respecto sueltas en la red, pero de todas las que revisé ninguna me funcionó bien. Así que me puse a tantear pequeñas variaciones hasta que una me funcionó y es la que les describiré a continuación: (aparentemente la falla de las ayudas que encontré se deben a una mala traducción y a errores de tipeo, asi que seré cuidadoso al respecto).
(probado con Ubuntu 11.04 Natty 64 bits)


1.- CONSEGUIR LOS ARCHIVOS DE REPOSITORIO (*.deb)
Bueno, para esta parte se necesitará irremediablemente internet, talvez de otra computadora con conexión y misma versión de ubuntu.
Las instalaciones hechas desde el synaptics guardan una copia de todas las dependencias descargadas y empleadas en la carpeta /var/cache/apt/archives.
Entonces, una PC a la que ya le hayan instalado el o los paquetes deseados via synaptics, tendrá todas las dependencias necesarias (archivos .deb) en esta carpeta.
Copien todo el contenido de esta carpeta (excepto la subcarpeta "partial" y el archivo "lock" que son solo de trabajo). Estos archivos serán su repositorio local.


2.- PREPARANDO A LA PC SIN INTERNET.
Creen una nueva carpeta en cualquier lugar, por ejemplo:
cd /home/$USER
mkdir misrepositorios
Dentro de esta carpeta creen otra (ahora si deben usar el nombre "Packages")
cd misrepositorios
mkdir Packages
Dentro de la carpeta Packages copien todos los archivos ".deb" que extrajeron de la otra PC.


3. PREPARANDO NUESTRO REPOSITORIO PARA SU USO
Ahora se creará el índice de nuestro repositorio local:
cd /home/$USER/misrepositorios/
dpkg-scanpackages Packages /dev/null | gzip > Packages/Packages.gz
Ahora se le indicará al synaptics donde buscar nuestra lista de repositorios:
sudo gedit /etc/apt/sources.list
En la parte final del archivo que se abrirá deberán añadir la línea: (¡¡respetar los espacios!!) (esta era otra fuente de error: la edición del archivo no acepta la variable "$USER", asi que aqui si hay que poner el usuario que corresponda a su pc. Si alguien sabe como usar variables en este archivo de texto, háganmelo saber)
deb file:/home/mi_usuario/misrepositorios/ Packages/
Guardan y cierran


Eso es todo. Si ahora le dan "recargar" al synaptics, leerá todos los repositorios de la carpeta como si lo estuvieran haciendo desde internet, y podrán hacer las instalaciones que deseen, siempre y cuando todas las dependencias hayan estado en su carpeta.

lunes, 2 de enero de 2012

detalles de compilacion de c++ en eclipse

Compilando en eclipse un programa hecho por otra persona en otra IDE se me presentaron los siguientes errores:

"multiple definition of _start"

el detalle en consola:
/build/buildd/eglibc-2.10.1/csu/../sysdeps/x86_64/elf/start.S:65: multiple definition of `_start'

Gracias a la publicación de Mario en un foro (http://stackoverflow.com/a/5528987) encontré la solución:
añadir el parametro -c a la compilación del g++ (en "other flags"). No volvió a aparecer el error.


Otro error que se me presentó a continuación:
" undefined reference to `pthread_create' "

a pesar de haberle añadido la opción -lpthread a la compilación con g++, me seguía arrojando el mismo error, hasta que caí en la cuenta que el eclipse trabaja por separado la compilación y el enlazado (link), así que el enlazado también debería incluir esta opción en "linker flags". Incluí de nuevo -lpthread en ese campo, y todo corrió perfecto.

Como siempre digo, aunque esta información es redundante, es mas fácil encontrarla en la web si está publicada en varios sitios y agrupada de forma distinta. Espero les sirva.

Saludos