Frank said:
Frank wrote:
[...] And there are several library functions
that *cannot* be declared free-hand, without their headers.
Which ones?
This would be a good time for you to review the Standard
library. It's grown a good deal with C99, but even in the C90
version you should be able to find several examples. Why don't
you just start trying to write free-hand declarations for all
the library functions you can think of, no headers allowed, and
see how far you get before running into a snag?
That might be a good way to test whether you *really* know these
functions. I can say with confidence that I do not.
I'd say I "know" about fifty percent of the Standard
library, taking "know" to mean "I never consult a reference
any more." I "sort of know" another twenty-five percent,
meaning that I can use the functions most of the time but
need to crack open a book for corner cases. And there's
another twenty-five percent that I just plain don't use and
can't claim familiarity with: Most of the new floating-point
and complex-variable functions of C99, the wide-character
functions, and the locale functions come to mind as stuff
my work simply doesn't involve. Even so, I know they exist
and would know that cracking a book would make them available
to me should the need ever arise. (Oh, and bsearch(): I find
it harder to remember how to call bsearch() than just to write
the search in open code.)
The only
reference to the Standard Library in Unleashed is the book of the same
name by PJ Plauger. Any opinions on this book?
If by "this book" you mean PJ Plauger's "The Standard C
Library," I think it excellent. C90-centered, but as I said
above most of the C99 additions are foreign to me anyhow.
What version does it have to be? I can pay between 7 and 54 dollars
for this on Amazon. I don't want anything that is tragically
outdated.
I don't know what you mean by this.
The #defines are more implementation specific than the function
prototypes, by necessity.
No, they're different. One names the fixed parameter and
has the `restrict' qualifier; the other doesn't. I claim that
the presence of the name makes no difference at all, barring
things like pre-existing macro definitions named `format'. As
to whether it's legal to omit the `restrict', I *believe* it is
but it's more a matter of faith than of reason.
I wish I knew how to bet on faith versus reason. Apparently, none of
the functions you referred to in your top-snipped post are in
stdlib.h:
#ifndef __stdlib_h__
#define __stdlib_h__
#include <stddef.h>
#include <_syslist.h>
#define MB_CUR_MAX 2
#define _MAX_PATH 260
#define _MAX_FNAME 256
#define _MAX_EXT 256
#define _MAX_DRIVE 3
#define _MAX_DIR 256
#undef RAND_MAX
#define RAND_MAX 0x7FFF
typedef struct {
int quot; /* quotient */
int rem; /* remainder */
} div_t;
typedef struct {
long quot; /* quotient */
long rem; /* remainder */
} ldiv_t;
typedef struct {
long long quot;
long long rem;
} lldiv_t;
#undef NULL
#define NULL ((void *)0)
#ifndef _WCHAR_T_DEFINED
typedef unsigned short wchar_t;
#define _WCHAR_T_DEFINED
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#endif
void abort(void);
int abs(int);
long long llabs(long long);
int atexit(void (*_func)(void));
double atof(const char *);
int atoi(const char *);
char *itoa(int,char *,int);
char *ltoa(long,char *,int);
void * bsearch(const void * _key,const void * _base, size_t _nmemb,
size_t _size,
int (*_compar)(const void *,const void *));
void * calloc(size_t _nmemb, size_t _size);
#if __LCCOPTIMLEVEL > 0
inline div_t __declspec(naked) div(int a,int b)
{
_asm("\tmovl\t(%esp),%eax");
_asm("\tmovl\t4(%esp),%ecx");
_asm("\tcdq");
_asm("\tidivl\t%ecx");
}
#else
div_t div(int _numer, int _denom);
#endif
void exit(int _status);
void _exit(int status);
#define _Exit _exit
void free(void *);
double strtod(const char *restrict nptr,char ** restrict endptr);
long double strtold(const char *restrict nptr,char ** restrict
endptr);
float strtof(const char *restrict nptr,char ** restrict endptr);
char * getenv(const char *_string);
long labs(long);
ldiv_t ldiv(long _numer, long _denom);
lldiv_t lldiv(long long numer,long long denom);
void * malloc(size_t _size);
void qsort(void * _base, size_t _nmemb, size_t _size, int(*_compar)
(const void *, const void *));
int rand(void);
void * realloc(void * _r, size_t _size);
void srand(unsigned _seed);
double strtod(const char *_n, char **_endvoid);
long double strtold(const char *,char **);
long long strtoll(const char *,char **,int);
unsigned long long strtoull(const char *,char **,int);
long strtol(const char *_n, char **_endvoid, int _base);
unsigned long strtoul(const char *_n, char **_end, int _base);
int system(const char *_string);
int putenv(const char *_string);
char * _gcvt(double,int,char *);
char * _fcvt(double,int,int *,int *);
char * ecvt(double,int,int *,int *);
int mbstowcs(wchar_t *,char *,size_t);
size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );
int mblen(char *,size_t);
int mbstrlen(char *s);
long atol(char *_nptr);
#ifndef __ANSIC__ONLY__
#include "safelib.h"
typedef void (*constraint_handler_t)( const char * restrict msg, void
* restrict ptr, errno_t error);
double frand(void);
constraint_handler_t set_constraint_handler_s( constraint_handler_t
handler);
constraint_handler_t get_constraint_handler_s( void );
void abort_handler_s( const char * restrict msg, void * restrict ptr,
errno_t error);
void ignore_handler_s( const char * restrict msg, void * restrict ptr,
errno_t error);
errno_t getenv_s(size_t * restrict len, char * restrict value, rsize_t
maxsize, const char * restrict name);
void *bsearch_s(const void *key, const void *base, rsize_t nmemb,
rsize_t size, int (*compar)(const void *k, const void *y, void
*context), void *context);
errno_t qsort_s(void *base, rsize_t nmemb, rsize_t size, int (*compar)
(const void *x, const void *y, void *context), void *context);
errno_t wctomb_s(int * restrict status, char * restrict s, rsize_t
smax, wchar_t wc);
errno_t mbstowcs_s(size_t * restrict retval, wchar_t * restrict dst,
rsize_t dstmax, const char * restrict src, rsize_t len);
errno_t wcstombs_s(size_t * restrict retval, char * restrict dst,
rsize_t dstmax, const wchar_t * restrict src, rsize_t len);
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
double wtof(const wchar_t *);
char *_fullpath( char *absPath, const char *relPath, size_t
maxLength );
void _makepath(char *path, const char *drive, const char *dir, const
char *fname, const char *ext );
void _splitpath(const char*, char*, char*, char*, char*);
#define _OUT_TO_DEFAULT 0
#define _OUT_TO_STDERR 1
#define _OUT_TO_MSGBOX 2
#define _REPORT_ERRMODE 3
extern int _sleep(unsigned long);
#define sleep _sleep
#define _mbstrlen mbstrlen
#define CRTAPI1
#define _fmode *(_imp___fmode_dll)
extern int _fmode;
extern char ***_imp___environ_dll;
#define _environ (*_imp___environ_dll)
extern unsigned int _osver;
extern unsigned int *(_imp___osver);
#define _osver *(_imp___osver)
extern unsigned int _winmajor;
extern unsigned int *(_imp___winmajor);
#define _winmajor *(_imp___winmajor)
extern unsigned int _winminor;
extern unsigned int *(_imp___winminor);
#define _winminor *(_imp___winminor)
extern unsigned int _winver;
extern unsigned int *(_imp___winver);
#define _winver *(_imp___winver)
void _searchenv(char *,char *,char *);
wchar_t * _itow (int, wchar_t *, int);
wchar_t * _ltow (long, wchar_t *, int);
unsigned short * _ultow (unsigned long, unsigned short *, int);
double wcstod(const wchar_t *, wchar_t **);
long wcstol(const wchar_t *, wchar_t **, int);
int wctomb(char *s,wchar_t wchar);
unsigned long wcstoul(const wchar_t *, wchar_t **, int);
wchar_t * _wgetenv(const wchar_t *);
int _wsystem(const wchar_t *);
int _wtoi(const wchar_t *);
long _wtol(const wchar_t *);
// Contains argv[0]
extern char * __declspec(dllimport) _pgmptr;
int _stdcall _lrotl(unsigned long,unsigned int);
int _stdcall _lrotr(unsigned int,unsigned int);
char *_i64toa(long long,char *,int);
char *_ui64toa(unsigned long long,char *,int);
long long _atoi64(const char *);
#define atoi64 _atoi64
char *_ultoa(unsigned long,char *,int);
unsigned short *_ultow(unsigned long,unsigned short *,int);
#define ultoa _ultoa
#define ultow _ultow
int _stdcall _System(const char *cmd,int nCmdShow);
#endif
#endif /* _STDLIB_H_ */
#include <stdio.h>
#include <string.h>
void Usage(char *programName)
{
fprintf(stderr,"%s usage:\n",programName);
/* Modify here to add your usage message when the program is
* called without arguments */
}
/* returns the index of the first argument that is not an option; i.e.
does not start with a dash or a slash
*/
int HandleOptions(int argc,char *argv[])
{
int i,firstnonoption=0;
for (i=1; i< argc;i++) {
if (argv
[0] == '/' || argv[0] == '-') {
switch (argv[1]) {
/* An argument -? means help is requested */
case '?':
Usage(argv[0]);
break;
case 'h':
case 'H':
if (!stricmp(argv+1,"help")) {
Usage(argv[0]);
break;
}
/* If the option -h means anything else
* in your application add code here
* Note: this falls through to the default
* to print an "unknow option" message
*/
/* add your option switches here */
default:
fprintf(stderr,"unknown option %s\n",argv);
break;
}
}
else {
firstnonoption = i;
break;
}
}
return firstnonoption;
}
int main(int argc,char *argv[])
{
if (argc == 1) {
/* If no arguments we call the Usage routine and exit */
Usage(argv[0]);
return 1;
}
/* handle the program options */
HandleOptions(argc,argv);
/* The code of your application goes here */
return 0;
}
This compiles on lcc.