2011-06-10 13 views
12

A pesar de haber leído K & R, y teniendo clases C siquiera se enseñan, me encuentro vergonzosamente incapaz de comprender plenamente lo que se podría llamar "moderna" C¿Dónde puedo encontrar recursos sobre la programación C "moderna"?

Parece que hay muchas convenciones no escritas en la programación moderna que , hasta donde yo sé, no están documentados en ningún lado.

Tome, por ejemplo, el código fuente SQLite. En lo que encuentro por ejemplo:

SQLITE_API int sqlite3_close(sqlite3 *); 

¿Qué representa para SQLITE_API? ¿Cómo es esto incluso sintácticamente correcto?

O esto:

#ifndef _SQLITE3_H_ 
#define _SQLITE3_H_ 

¿Hay una convención aceptada en algún lugar cuando el prefijo macros con guiones? A veces veo macros con el prefijo con dos guiones bajos.

O qué tal el uso de tipos de tamaño fijo, como uint32 y así sucesivamente. ¿Cuándo debería uno usar esta práctica, y cuándo no? ¿Qué pasa con el tipo new-ish bool, cuando debería ser preferible a los simples?

Estas son algunas de las preguntas que planteo cuando leo el código fuente de otras personas. ¿Hay alguna referencia en alguna parte que pueda ayudarme a responder estas preguntas?

+3

Lea http://c-faq.com/ Luego obtenga el estándar ISO C99 y léalo. – cnicutar

+0

Estos también se conocen como Ansi C, también se pueden buscar estándares de codificación GNU o algo muy específico sería el estilo de codificación del kernel de Linux. Berkeley también tiene algunas pautas de codificación. Todos ellos tienen pros y contras. Además, hay mucho más por ahí. –

Respuesta

4

SQLITE_API en un código como este es muy probable que un preprocesador defina, que se preocupe por exponer la llamada, p. una biblioteca DLL compilada Eso es bastante común.

Si todo está en mayúscula en C, es probable que sea un símbolo de preprocesador, y una buena idea suele ser ejecutar el juego a través del preprocesador y leer lo que sale.

2

Este

#ifndef _SQLITE3_H_ 
#define _SQLITE3_H_ 

es sólo un protector contra la inclusión múltiple.

Impide errores en el caso de que xxx.h incluya este archivo, así como yyy.h, y yyy.h también incluye este archivo.

+1

No estaba preguntando sobre incluir guardias (alguien que enseña a personas C debe saber sobre ellas, al menos realmente lo espero), pero sobre el uso de guiones bajos prefijados (estrictamente hablando, están reservados para ser utilizados por la implementación). – delnan

+1

"Todos los identificadores que comienzan con un guión bajo y una letra mayúscula u otro guión bajo siempre están reservados para cualquier uso". (C99, §7.1.3 ¶1) –

1

No creo que haya una gran referencia para esto. Lo que está presenciando es una serie de convenciones, algunas muy utilizadas en la industria y otras posiblemente más específicas de su propia base de códigos, que han surgido para manejar desafíos o situaciones estándar en proyectos de software a gran escala en C (y derivados) Como nota, K & R es una gran herramienta de enseñanza, pero no aborda ninguna de estas convenciones de proyectos a gran escala, que en su mayoría han aparecido orgánicamente y dentro de la industria.

Ofrecen dos excelentes ejemplos. El primero es un #define d en algún lugar para decorar una función para que se exporte correctamente o simplemente se documente que se va a exportar. El segundo patrón se llama "include guard" (ver enlace) y los guiones bajos convencionales son opcionales, pero son una buena forma de evitar el conflicto con las definiciones normales de números mágicos.

Existen muchas convenciones, muchas involucran al preprocesador con definiciones y macros. Su mejor opción es, probablemente, mirar hacia arriba y preguntar sobre cada patrón individualmente. Es probable que obtenga aquí respuestas reflexivas sobre la lógica y una buena discusión.

0

Expert C Programming Es un gran seguimiento para K & R. No se deje intimidar por el título. Es un libro muy accesible si conoces los conceptos básicos de C. Se trata de una gran cantidad de situaciones del código del mundo real que K & R es bastante corta.

Dicho esto, realmente no hay sustituto para leer y escribir código. La mayoría de las convenciones modernas no son realmente estándares y, a menudo, se cumplen de manera diferente en diferentes bases de códigos. Son solo soluciones comunes a los problemas y limitaciones que todos enfrentan al escribir en el idioma. Lo más importante en mi opinión es entender cuáles son esos problemas y limitaciones.

2

SQLITE_API es un ejemplo de lo que llamo el 'idioma del tipo de llamada'. Es una directiva de preprocesador utilizada para mejorar la portabilidad en los archivos de encabezado, donde el archivo de encabezado debe definir algún modo de llamada específico, generalmente entre el código principal y una DLL o similar.

Dependiendo de la plataforma y el compilador en uso SQLITE_API por lo general a ampliar alguna combinación de las convenciones de llamada disponibles, como cdecl,__stdcall or similar.

Usted debe encontrar la definición de la misma en el archivo de cabecera.

0

En primer lugar, debe tener en cuenta que la definición de "_SQLITE3_H_" está realmente prohibida, se reservan todos los nombres que comienzan con un guión bajo seguido de otro guión bajo o una letra mayúscula. Cuando lo haces, la respuesta simple es que probablemente sea mejor evitar el uso de un guión bajo inicial en cualquier cosa que definas. Déjalos para la implementación.

En lo que respecta al SQLLITE_API, es probablemente definido de manera diferente en diferentes plataformas. Si estás construyendo como un archivo DLL en Windows, por ejemplo, es probable que se define algo como:

#define SQLLITE_API __declspec(dllexport) __stdcall 

Por otro lado, cuando se está utilizando la cabecera en el código, es probable que se expandió a algo así como:

#define SQLLITE_API __declspec(dllimport) __stdcall 

Estos básicamente indican al compilador que cuando está la construcción de la DLL desea que la función exportada (por lo que es visible para el resto del mundo). Cuando lo está utilizando en su propio código, le dice al compilador que la función en cuestión vendrá de una DLL.

3

Los estándares de codificación Afaik GNU están en constante revisión/actualización, por lo que podría ser una buena instantánea del estilo 'moderno'.

http://www.gnu.org/prep/standards/

Re: undercores específicamente simples o dobles, en mi experiencia y por lo que a menudo leo; es groseramente aceptado más seguro para evitar los prefijos de subrayado doble ya que estos son generalmente 'reservados' para framework/system/compiler-specific y elementos relacionados con el compilador, por lo tanto, macros soley para usar dentro del módulo/paquete/unidad/proyecto que se definen deben evitar ser undescore-prefijado en absoluto.

La mayoría de las instituciones tienen sus propios estándares y pautas de codificación de idiomas, que pueden variar bastante significativamente. Como siempre, la consistencia es la clave.

+0

¿Estás aquí? ¡Bienvenido! – lindelof

0

Recomendaría "C Interfaces e implementaciones: técnicas para crear software reutilizable" de David R. Hanson.Creo que este es uno de los mejores libros sobre el uso del lenguaje C.

Cuestiones relacionadas