MediaWiki API result

This is the HTML representation of the JSON format. HTML is good for debugging, but is unsuitable for application use.

Specify the format parameter to change the output format. To see the non-HTML representation of the JSON format, set format=json.

See the complete documentation, or the API help for more information.

{
    "batchcomplete": "",
    "continue": {
        "gapcontinue": "Standard_Library_Functions",
        "continue": "gapcontinue||"
    },
    "query": {
        "pages": {
            "10": {
                "pageid": 10,
                "ns": 0,
                "title": "Specific Features",
                "revisions": [
                    {
                        "contentformat": "text/x-wiki",
                        "contentmodel": "wikitext",
                        "*": "The HI-TECH C compiler has a number of features,  which while  largely compatible with other C compilers, contribute to more reliable programming methods.\n\n== ANSI C Standard Compatibility ==\n\nAt the time of writing the Draft ANSI Standard for  the C Language was at an advanced stage, though not yet an official standard. Accordingly it is not possible to claim  compliance  with  that standard, however HI-TECH C includes the\nmajority of the new and altered features in the  draft  ANSI standard.  Thus  it  is in the sense that most people understand it \"ANSI compatible\".\n\n== Type Checking ==\n\nPrevious C compilers have adopted  a  lax  approach  to type  checking.  This  is  typified  by the Unix C compiler, which allows almost arbritary mixing  of  types  in  expressions. The HI-TECH C compiler performs much more strict type\nchecking, although in most cases only warning  messages  are issued,  allowing  compilation  to proceed if the user knows that the errors are harmless. This would occur, for example, when  an  integer  value was assigned to a pointer variable. The generated code would almost certainly be what  the  user intended,  however if in fact it represented an error in the source code, the user is prompted to check  and  correct  it where necessary.\n\n== Member Names ==\n\nIn early C compilers member names in  different  structures were required to be distinct except under certain circumstances. HI-TECH C, like most recent  implementations  of C, allows member names in different structures and unions to\noverlap.  A member name is recognized only in the context of an  expression  whose type is that of the structure in which the member is defined.  In practice this means that a member name  will  be recognized only to the right of a '.' or '->'operator, where the expression to the left of  the  operator is  of  type  structure  or pointer to structure the same as that in which the member name was declared.  This  not  only allows  structure  names  to  be re-used without conflict in more than one structure, it permits strict checking  of  the\nusage  of  members; a common error with other C compilers is the use of a member name with a  structure  pointer  of  the wrong type, or worse with a variable which is a pointer to a simple type.\n\nThere is however an escape from this,  where  the  user desires to use as a structure pointer something which is not declared as such. This is via the use  of  a  typecast.  For example, suppose it is desired to access a memory-mapped i/o\ndevice, consisting of several  registers.  The  declarations and use may look something like the code fragment in fig. 2.\n\n struct io_dev\n {\n short   io_status;    /* status */\n char    io_rxdata;    /* rx data */\n char    io_txdata;    /* tx data */\n };\n \n #define RXRDY   01           /* rx ready */\n #define TXRDY   02           /* tx ready */\n \n /* define the (absolute) device address */\n \n #define DEVICE  ((struct io_dev *)0xFF00)\n \n send_byte(c)\n char c;\n {\n /* wait till transmitter ready */\n while(!(DEVICE->io_status & TXRDY))\n continue;\n /* send the data byte */\n DEVICE->io_txdata = c;\n }\n\n;Fig. 2. Use of Typecast on an Absolute Address\n\n\nIn this example, the device in question has  a  16  bit status  port,  and  two 8 bit data ports. The address of the device (i.e. the address of its status  port)  is  given  as (hex)0FF00.  This address is typecast to the required struc-\nture pointer type to enable  use  of  the  structure  member names.  The  code generated by this will use absolute memory references to access the device, as required.\n\nSome examples of right and wrong usage of member  names are shown in fig. 3.\n\n== Unsigned Types ==\n\nHI-TECH C implements unsigned versions of all  integral types;  i.e.   unsigned  char,  short,  int and long.  If an unsigned quantity is shifted right, the shift will  be  performed  as  a  logical  shift,  i.e. bringing zeros into the\nrightmost bits. Similarly right shifts of a signed  quantity will sign extend the rightmost bits.\n\n== Arithmetic Operations ==\n\nOn machines where arithmetic  operations  may  be  performed   more  efficiently  in  lengths  shorter  than  int, operands shorter than int will not be extended to int length unless necessary.\n\nFor example, if two characters are added and the result stored  into  another  character,  it  is  only necessary to\n\n struct fred\n {\n char      a;\n int       b;\n }     s1, * s2;\n \n struct bill\n {\n float   c;\n long    b;\n }       x1, * x2;\n \n main()\n {\n /* wrong - c is not a member of fred */\n s1.c = 2;\n \n /* correct */\n s1.a = 2;\n \n /* wrong - s2 is a pointer */\n s2.a = 2;\n \n /* correct */\n x2->b = 24L;\n \n /* right, but note type conversion\n from long to int */\n s2->b = x2->b;\n }\n\n;Fig. 3. Examples of Member Usage\n\nperform arithmetic in 8 bits, since any  overflow  into  the top  8 bits will be lost. However, if the sum of two characters is stored into an int, the addition should be  done  in 16 bits to ensure the correct result.\n\nIn accordance with the draft ANSI standard,  operations on  float rather than double quantities will be performed in the shorter precision rather than being converted to  double precision then back again.\n\n== Structure Operations ==\n\nHI-TECH C implements structure  assignments,  structure arguments  and structure-valued functions in their full generality. The example in fig. 4 is  a  function  returning  a structure. Some legal (and illegal) uses of the function are\nalso shown.\n\n struct bill\n {\n char    a;\n int     b;\n }\n afunc()\n {\n struct bill     x;\n \n return x;\n }\n \n main()\n {\n struct bill     a;\n \n a = afunc();            /* ok */\n pf(\"%d\", afunc().a);    /* ok */\n \n /* illegal, afunc() cannot be assigned\n to, therefore neither can\n afunc().a */\n afunc().a = 1;\n \n /* illegal, same reason */\n afunc().a++;\n }\n\n;Fig. 4. Example of a Function Returning a Structure\n\n== Enumerated Types ==\n\nHI-TECH C supports enumerated types;  these  provide  a structured way of defining named constants.\n\nThe uses of enumerated types are more  restricted  than that  allowed by the Unix C compiler, yet more flexible than permitted  by  LINT.  In  particular,   an   expression   of enumerated type may be used to dimension arrays, as an array\nindex or as the operand of a switch  statement.   Arithmetic may  be  performed  on enumerated types, and enumerated type expressions may be compared, both for equality and with  the relation  operators.  An example of the use of an enumerated type is given in fig. 5.\n\n== Initialization Syntax ==\n\nKernighan and Ritchie in \"The C  Programming  Language\" state  that  pairs of braces may be omitted from an initializer in certain contexts; the draft ANSI  standard  provides that  a  conforming C program must either include all braces\nin an initializer, or leave them all out. HI-TECH  C  allows any  pairs  of braces to be omitted providing that the front end of the compiler can determine the  size  of  any  arrays being  initialized, and providing that there is no ambiguity as to which braces have been omitted. To avoid ambiguity  if any  pairs of braces are present then any braces which would\n\n /* a represents 0, b -> 1 */\n enum fred { a, b, c = 4 };\n \n main()\n {\n enum fred       x, y, z;\n \n x = z;\n if(x < z)\n func();\n x = (enum fred)3;\n switch(z) {\n case a:\n case b:\n default:\n }\n }\n\n;Fig. 5. Use of an Enumerated Type\n\nenclose those braces must also be present. The compiler will complain  (\"initialization  syntax\")  if  any  ambiguity  is present.\n\n== Function Prototypes ==\n\nA new feature of C included in the proposed ANSI for C, known  as \"function prototypes\", provides C with an argument checking facility, i.e. it allows the compiler to  check  at compile  time  that  actual arguments supplied to a function\ninvocation  are  consistent  with  the   formal   parameters expected  by the function. The feature allows the programmer to include in a function  declaration  (either  an  external declaration or an actual definition) the types of the parameters to that function.   For  example,  the  code  fragment shown in fig. 6 shows two function prototypes.\n\n void fred(int, long, char *);\n \n char *\n bill(int a, short b, ...)\n {\n return a;\n }\n\n;Fig. 6. Function Prototypes\n\n\nThe first prototype is an external declaration  of  the function  <strong>fred()</strong>,  which  accepts  one integer argument, one long argument, and one argument which is a pointer to  char. Any  usage  of  <strong>fred()</strong> while the prototype declaration is in scope will cause the actual parameters  to  be  checked  for number  and  type  against  the  prototype, e.g. if only two arguments were supplied or an integral  value  was  supplied for the third argument the compiler would report an error.\n\n\nIn the second example, the function <strong>bill()</strong> expects  two or more arguments. The first and second will be converted to int and short respectively, while the remainder (if present) may  be  of any type. The ellipsis symbol (...) indicates to the compiler that zero or more arguments  of  any  type  may follow the other arguments. The ellipsis symbol must be last in the argument list, and may not appear as the  only  argument in a prototype.\n\nAll prototypes for a function must agree exactly,  however  it  is legal for a definition of a function in the old style,  i.e.  with  just  the  parameter  names  inside  the parentheses,  to follow a prototype declaration provided the number and type of the arguments agree. In this case  it  is essential  that  the  function definition is in scope of the prototype declaration.\n\nAccess to unspecified arguments  (i.e.  arguments  supplied where an ellipsis appeared in a prototype) must be via the macros defined  in  the  header  file  <stdarg.h>.  This defines the macros <strong>va_start, va_arg</strong> and <strong>va_end.</strong> See <strong>va_start</strong> in the library function listing for more information.\n\nNOTE that is is a grave error to use a  function  which has  an  associated  prototype  unless  that prototype is in scope, i.e. the prototype MUST be declared  (possibly  in  a header  file)  before  the  function is invoked.  Failure to comply with this rule may result in strange behaviour of the program.  HI-TECH  C  will  issue a warning message (\"func() declared  implicit  int\")  whenever  a  function  is  called without  an  explicit  declaration.   It is good practice to declare all functions and global variables in  one  or  more header  files  which are included wherever the functions are defined or referenced.\n\n== Void and Pointer to Void ==\n\nThe <strong>void</strong> type may be used to indicate to  the  compiler that  a  function  does not return a value. Any usage of the return value from a void function  will  be  flagged  as  an error.\n\nThe type <strong>void</strong> *, i.e. pointer to void, may be used as a \"universal\"  pointer type. This is intended to assist in the writing of general purpose storage allocators and the  like, where a pointer is returned which may be assigned to another variable of some other pointer type.  The  compiler  permits without  typecasting  and  without  reporting  an  error the conversion of <strong>void</strong> * to any  other  pointer  type  and  vice versa.  The programmer is advised to use this facility carefully and ensure that any  <strong>void</strong>  *  value  is  usable  as  a pointer  to  any  other type, e.g. the alignment of any such pointer should be suitable for storage of any object.\n\n== Type qualifiers ==\n\nThe ANSI C standard  introduced  the  concept  of  <strong>typequalifiers</strong> to C; these are keywords that qualify the type to which they are applied.  The type qualifiers defined by ANSI C are const and volatile.  HI-TECH C also implements several other type qualifiers.  The extra qualifiers include:\n\n:far\n:near\n:interrupt\n:fast interrupt\n:port\n\nNot all versions of the compilers implement all of the extra qualifiers.  See  the  machine dependent section for further information.\n\nWhen constructing declarations using  type  qualifiers, it  is very easy to be confused as to the exact semantics of the declaration. A couple of rules-of-thumb will  make  this easier.  Firstly, where a type qualifier appears at the left of a declaration  it  may  appear  with  any  storage  class specifier and the basic type in any order, e.g.\n\n static void interrupt   func();\n\nis semantically the same as\n\n interrupt static void   func();\n\n\nWhere a qualifier appears in this context,  it  applies to  the  basic  type  of  the declaration. Where a qualifier appears to the right of  one  or  more  '*'  (<strong>star</strong>)  pointer modifiers,  then  you should read the declaration from right to left, e.g.\n\n char * far fred;\n\nshould be read as \"fred is a  far  pointer  to  char\".  This means  that  fred is qualified by <strong>far</strong>, not the char to which it points. On the other hand,\n\nchar far * bill;\n\nshould be read as \"bill is a pointer to a  far  char\",  i.e. the  char to which bill points is located in the far address space. In the context of the 8086 compiler  this  will  mean that  bill  is  a  32  bit  pointer  while  fred is a 16 bit pointer. You will hear bill referred to as a \"far  pointer\",however the terminology \"pointer to far\" is preferred.\n\n\n== 5.12.==\n\nThere are two methods provided  for  in-line  assembler code  in  C  programs.   The  first  allows several lines of assembler anywhere in a program. This is via  the  #asm  and #endasm  preprocessor  directives.   Any lines between these\ntwo directives will be copied straight through to the assembler  file  produced  by the compiler. Alternatively you can use the asm(\"<strong>string</strong>\"); construct anywhere a C  statement  is expected. The <strong>string</strong> will be copied through to the assembler file. Care should be  taken  with  using  in-line  assembler since it may interact with compiler generated code.\n\n== Pragma Directives ==\n\nThe draft  ANSI  C  standard  provides  for  a  #pragma preprocessor  directive that allows compiler implementations to control  various  aspects  of  the  compilation  process. Currently  HI-TECH  C  only  supports  one  pragma, the <strong>pack</strong> directive. This allows control  over  the  manner  in  which members  are  allocated inside a structure. By default, some of the compilers (especially the 8086 and  68000  compilers) will  align structure members onto even boundaries to optimize machine accesses. It is sometimes  desired  to  override this  to achieve a particular layout inside a structure. The <strong>pack</strong> pragma allows specification of a maximum  packing  factor.  For  example,  #pragma pack1(1) will instruct the compiler that no additional padding be inserted between  struc\nture  members,  i.e.  that  all members should be aligned on boundaries divisible by 1. Similarly  #pragma  pack(2)  will allow  alignment  on  boundaries  divisible by 2. In no case will use of the <strong>pack</strong> pragma force a greater  alignment  than would have been used for that data type anyway.\n\nMore that one <strong>pack</strong> pragma may be used in a program. Any use  will  remain  in force until changed by another <strong>pack</strong> or until the end of the file. Do not use a <strong>pack</strong>  pragma  before include files such as <<strong>stdio.h</strong>> as this will cause incorrect declarations of run-time library data structures."
                    }
                ]
            },
            "13": {
                "pageid": 13,
                "ns": 0,
                "title": "Standard Libraries",
                "revisions": [
                    {
                        "contentformat": "text/x-wiki",
                        "contentmodel": "wikitext",
                        "*": "== Standard I/O ==\n\nC is a language which does not specify the  I/O  facilites in the language itself; rather all I/O is performed via library routines. In practice this results in  I/O  handling which  is  no  less convenient than any other language, with\nthe added possibility of customising the I/O for a  specific application. For example it is possible to provide a routine to replace the standard getchar() (which gets one  character from  the  standard input) with a special getchar(). This is particulary useful when writing code which is to  run  on  a special  hardware  configuration,  while  maintaining a high level of compatibility with \"standard\" C I/O.\n\nThere is in fact a Standard I/O library  (STDIO)  which defines  a  portable set of I/O routines. These are the routines which are normally used by any C application  program. These  routines,  along with other non-I/O library routines,\nare listed in detail in a subsequent section of the manual.\n\n== Compatibility ==\n\nThe libraries supplied with HI-TECH C are highly compatible  with  the  ANSI  libraries,  as  well  as the V7 UNIX libraries, both at the Standard I/O level and the UNIX  system  call  level.  The Standard I/O library is complete, and\nconforms in all respects with the UNIX Standard I/O library. The  library  routines  implementing  UNIX  system call like functions are as close as possible to  those  system  calls, however  there  are  some  UNIX  system calls that cannot be simulated on other systems, e.g.  the link() operation. However  the  basic  low  level I/O routines, i.e. open, close, read, write and lseek are identical to the UNIX equivalents. This  means  that many programs written to run on UNIX, even if they do not use Standard I/O, will run with little modification when compiled with HI-TECH C.\n\n== Libraries for Embedded Systems ==\n\nThe cross compilers, designed to produce code for  target  systems  without  operating  systems, are supplied with libraries implementing a subset of the STDIO functions.  Not provided  are  those  functions dealing with files. Included\nare <strong>printf(), scanf()</strong> etc. These operate by calling two  low level  functions  <strong>putch</strong> and <strong>getch()</strong> which typically send and receive characters via a serial port. Where the compiler  is aimed  at  a  single-chip  micro  with on-board UART this is used.  The source code for all these functions  is  supplied enabling the user to modify it to address a different serial port.\n\n== Binary I/O ==\n\nOn some operating  systems,  notably  CP/M,  files  are treated  differently according to whether they contain ASCII (i.e. printable) or binary data.  MD-DOS also  suffers  from this  problem,  not  due to any lack in the operating system\nitself, but rather because of the hangover from  CP/M  which results  in  many programs putting a redundant ctrl-Z at the end of files.  Unfortunately there is no  way  to  determine which  type  of  data a file contains (except perhaps by the name or type of the file, and  this  is  not  reliable).  To overcome  this difficulty, there is an extra character which may be included in the MODE string to  a  fopen()  call.  To open a file for ASCII I/O, the form of the fopen() call is:\n\n fopen(\"filename.ext\", \"r\")      /* for reading */\n fopen(\"filename.ext\", \"w\")      /* for writing */\n\nTo open a file for binary I/O,  the  character  'b'  may  be\nappended to the\n\n fopen(\"filename.ext\", \"rb\")\n fopen(\"filename.ext\", \"wb\")\n\n\nThe additional character instructs  the  STDIO  library that  this file is to be handled in a strict binary fashion. On CP/M or MS-DOS, a file opened in ASCII mode will have the following  special character handling performed by the STDIO\nroutines:\n\n;newline\n:('\\n') converted to carriage return/newline on output.\n\n;return\n:('\\r') ignored on input\n\n;Ctrl-Z\n:interpreted as End-Of-File on input and, for CP/M only, appended when closing the file.\n\nThe special actions performed  on  ASCII  files  ensure that  the  file is written in a format compatible with other programs handling text files, while eliminating the requirement for any special handling by the user program - the file\nappears to the user program as though it  were  a  UNIX-like text file.\n\nNone of these special actions are performed on  a  file opened  in  binary mode.  This is required when handling any kind of binary data, to ensure that spurious bytes  are  not inserted, and premature EOF's are not seen.\n\nSince the binary mode character is  additional  to  the normal  mode  character, this usage is quite compatible with UNIX C. When compiled on UNIX, the additional character will be ignored.\n\nA mention here of the  term  `stream'  is  appropriate; stream  is used in relation to the STDIO library routines to mean the source or sink of bytes (characters) manipulated by those  routines.  Thus the FILE pointer supplied as an argu-\nment to the STDIO routines may be regarded as  a  handle  on the  corresponding  stream.   A  stream  may  be viewed as a featureless sequence of bytes,  originating  from  or  being sent  to  a  device or file or even some other indeterminate source. A FILE pointer should not be confused with the 'file descriptors'  used  with the low-level I/O functions <strong>open(), close(), read()</strong> and <strong>write()</strong>. These form an independent group of  I/O  functions which perform unbuffered reads and writes to files.\n\n== Floating Point Library ==\n\nHI-TECH C  supports  floating  point  as  part  of  the language,  however  the  Z80  implementation provides single precision only; double floats are permitted but are no  different   to  floats.  In  addition,  the  standard  library,\nLIBC.LIB, does not  contain  any  floating  point  routines. These   have   been  separated  out  into  another  library, LIBF.LIB. This means that if this library is not searched no floating  point  support  routines  will  be linked in, thus avoiding any size penalty for the floating point support  if it is not used. This is particulary important for printf and scanf, and thus LIBF.LIB contains  versions  of  printf  and scanf that do support floating point formats.\n\nThus, if floating point is used, a -LF option should be used  AFTER the source and/or object files to the C command. E.g.:\n\n C -V -O x.c y.c z.obj -LF"
                    }
                ]
            }
        }
    }
}