<ansi_h> (and Microsoft C [e.g. Visual Studio] Aarrrgggghhhhh...)

Anything QL Software or Programming Related.
Post Reply
User avatar
ql_freak
Gold Card
Posts: 354
Joined: Sun Jan 18, 2015 1:29 am

<ansi_h> (and Microsoft C [e.g. Visual Studio] Aarrrgggghhhhh...)

Post by ql_freak »

I'm currently working on a new C program. First of all I'm porting the "ansi_h" header file from C68/PDQC, so that it will also be compatible with the QLC (normal Lattice C compiler for the QL) and EJC _AND_ (it's more easy to write a C program for Visual Studio C, and port it back to QDOS C) Microsoft C. The ansi_h file seems to be correct, but Microsoft C is horrible:

Code: Select all

void myfunc() {
    FILE *fp;
    ...
    fp = fopen("myfile", "rb");
    /* BOOM (with Microsoft C):
       Schweregrad  Code description project file line Unterdrückungszustand
       Error C4996  'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation,
       use_CRT_SECURE_NO_WARNINGS. See online help for details.  viewsroff  d:\home\hps\projects\c\qdos\viewsroff\vsroff.c   206	
    */
}
OK here my corrected <ansi_h> file (just a first try), which seems to be compatible with EJC (and hopefully with PDQC and C68) which seems to be compatible with Microsoft C from Visual Studio [2015], except for the problems with fopen and sscanf). The QLC (Lattice) compiler does unfortunately NOT support preprocessor statements like
#if (COMPILER == C68)
only
#if COMPILER
can be used (is true if COMPILER is not 0)
The improved Atari Compiler from PDQC does (but can currently not be used with EJC).

Can anyone test this improved ansi.h with C68 (I have not installed C68), if it's compatible?

Code: Select all

#ifndef QDOS
#pragma once
#endif
/* The <ansi.h> header checks whether the compiler claims conformance to ANSI
* Standard C. If so, the symbol _ANSI is defined as 1, otherwise it is
* defined as 0.  Based on the result, a macro
*
*  _PROTOTYPE(function, params)
*
* is defined.  This macro expands in different ways, generating either
* ANSI Standard C prototypes or old-style K&R (Kernighan & Ritchie)
* prototypes, as needed.  Finally, some programs use _CONST, _VOIDSTAR etc
* in such a way that they are portable over both ANSI and K&R compilers.
* The appropriate macros are defined here.
*/

#ifndef _ANSI_H
#define _ANSI_H

/* ANSI C requires __STDC__ to be defined as 1 for an ANSI C compiler.
* Some half-ANSI compilers define it as 0.  Get around this here.
*/

#define _ANSI              0    /* 0 if compiler is not ANSI C, 1 if it is */

/*
*  Try and determine the compiler being used
*/
#ifdef _MSC_VER /* Microsoft C (e.g. C from VisualStudio) */
#define COMPILER MICROSOFTC
#define __STDC__ 1
#else
#ifdef TOS
#define COMPILER    PDQC
#define LATTICE     1
#define __STDC__    0
#else
#ifdef QDOS
#  ifdef COMPILER
#    if (COMPILER == C68)
#      define C68   1
#    else
/* if COMPILER != C68, you can extend other QDOS compilers here */
#      define COMPILER UNKNOWN
#    endif /* if COMPILER */
#  else
#    define COMPILER    QLC
#    define COMPILER_QLC 1
#    define LATTICE     1
#    define __STDC__    0
#  endif /* ifdef COMPILER */
#endif /* QDOS */
#endif /* TOS */
#endif /* _MSC_VER */

#ifndef _MSC_VER
#ifndef QDOS
#define QDOS    1
#endif
#ifndef COMPILER
#define COMPILER    UNKNOWN
#endif /* QDOS */
#endif /* _MSC_VER */

#ifdef __STDC__         /* __STDC__ defined for (near) ANSI compilers*/
#if __STDC__            /* __STDC__ != 0 for conformant compilers */
#undef _ANSI            /* get rid of above definition */
#define _ANSI   1       /* _ANSI = 1 for ANSI C compilers */
#endif
#endif

/* At this point, _ANSI has been set correctly to 0 or 1. Define the
* _PROTOTYPE macro to either expand both of its arguments (ANSI prototypes),
* only the function name (K&R prototypes).
*/

/* #if _ANSI || LATTICE */ /* Not supported by QL Lattice C */
#ifdef _ANSI
#if _ANSI
#define XYZ "XYZ_IS_DEFINED\n" /* I think this can be deleted, I have just used it for a test  */
#define _PROTOTYPE(function, params)    function params
#define _VOIDSTAR   void *
#define _VOID       void
#define _CONST      const
#define _VOLATILE   volatile
#define _SIZET      size_t
#endif /* if _ANSI */
#else
#if LATTICE
#ifdef COMPILER_QLC
#define _PROTOTYPE(function, params)    function params
#define _VOIDSTAR   void *
#define _VOID       void
#define _CONST
#define _VOLATILE
#define _SIZET      int
#else
#define _PROTOTYPE(function, params)    function params
#define _VOIDSTAR   void *
#define _VOID       void
#define _CONST      const
#define _VOLATILE   volatile
#define _SIZET      size_t
#endif /* COMPILER_QLC */
#endif LATTICE
#endif /* _ANSI */

#else

#define _PROTOTYPE(function, params)    function()
#define _VOIDSTAR   void *
#define _VOID       void
#define _CONST
#define _VOLATILE
#define _SIZET      int

#endif /* _ANSI_H */


http://peter-sulzer.bplaced.net
GERMAN! QL-Download page also available in English: GETLINE$() function, UNIX-like "ls" command, improved DIY-Toolkit function EDLINE$ - All with source. AND a good Python 3 Tutorial (German) for Win/UNIX :-)
User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: <ansi_h> (and Microsoft C [e.g. Visual Studio] Aarrrgggghhhhh...)

Post by tofro »

Peter,

I'm not sure what you are trying to achieve.

Just some comments:
  • Your ANSI_h header file runs through C68, but probably does not do what you expect it to do (I'm not actually sure what that is...).
  • C68 doesn't like "__STDC__" to be redefined in -ansi mode and gives a warning
  • If you invoke C68 with "-ansi" to support ANSI-C prototypes, "C68" (and "QDOS") will not be defined! - Your detection of the compiler does not seem to work. C68 actually does expose itself as an ANSI compiler, and you can, in fact, throw relatively "modern" code at it without choking in -ansi mode. What you're doing here seems a bit obsolete to me.
  • C68 in fact claims to be an ANSI compiler - if invoked with "-ansi", it will define "__STDC__"
  • Keep in mind that with messing with the "_" and "__"-prefixed symbols you're actually modifying stuff that's better left alone. C68 has a pretty elaborate mess of macros to do exactly what you (seem to) want to do.
  • What you call "PROTOTYPE", actually seems to be the _P() macro in C68.
  • You are missing proper include guards for compilers that don't understand #pragma once (C68 does, so you could use it there)
I'm afraid you will not get around installing C68. It's macro trickery in the standard headers (to achieve ANSI compatibility) is way too elaborate already to mess with it remotely.

BTW: MS Visual C may not be as bad as you seem to think - That warning can easily be switched off by defining "_CRT_SECURE_NO_DEPRECATE" on the project's preprocessor definitions.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
NormanDunbar
Forum Moderator
Posts: 2277
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: <ansi_h> (and Microsoft C [e.g. Visual Studio] Aarrrgggghhhhh...)

Post by NormanDunbar »

While I'm not 100% sure about Visual C, I do recall that Visual C++ was often slated for its non-conformance to standads, but hey, Microsoft back in the day. They are better now.

My favourite C and C++ compiler on Windows, back in the day, was Borland. Now sadly defunct. However, before they "died" they gave away a free, commandline, set of tools based on their C++ compiler version 5. I used it for years, at home and at work.

Embarcadero took over and fairly recently/some time ago (depending on when you are reading this) updated the freebie to version 10, which is quite up to date. You can read about it and get it at:

https://www.embarcadero.com/free-tools/ccompiler

You will need an account, but you get very few emails. If they give you free stuff, it seems only fair to "suffer" a couple of emails a quarter, no?

Also available for free is Delphi and C++ Builder, if those fit your needs. There is other stuff too.

I used the compiler standalone in make files, Borland make is supplied by the way, and in the Code::Blocks IDE, when I "needed" and IDE.

Oh, yes, one feature, it's 32 bit only -- unless they changed things recently.

Download.
Uncompress into a folder.
Add to %path%.
Enjoy


Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Post Reply