SonarOpenCommunity / sonar-cxx

SonarQube C++ Community plugin (cxx plugin): This plugin adds C++ support to SonarQube with the focus on integration of existing C++ tools.
GNU Lesser General Public License v3.0
1k stars 365 forks source link

Split System and Project includes and macros #86

Closed guwirth closed 8 years ago

guwirth commented 10 years ago

It would be helpful to separate

Typically system header files and macros are stable and do not change on an environment. Only the project header files and macros are changing in each project.

This would make it possible to set system related stuff only once.

By the way: Which macros are predefined by the plugin at the moment (DATE, TIME, FILE, LINE, ...)?

Proposal:

sonar.cxx.systemIncludes=... sonar.cxx.systemDefines=... sonar.cxx.projectIncludes=... sonar.cxx.projectDefines =...

wenns commented 10 years ago

I agree.

As for the predefined macros: you find them here: https://github.com/wenns/sonar-cxx/blob/master/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/StandardDefinitions.java

guwirth commented 10 years ago

Other tools does not predefine any macros other than DATE, TIME, FILE, and LINE.

The first C Standard specified that the macro STDC be defined to 1 if the implementation conforms to the ISO Standard and 0 otherwise, and the macro STDC_VERSION defined as a numeric literal specifying the version of the Standard supported by the implementation. Standard C++ compilers support the __cplusplus macro. Compilers running in non-standard mode must not set these macros, or must define others to signal the differences.

The macros STDC and cplusplus are mostly not predefined because different compilers may define them to different values. For example, the ISO C++ standard says that cplusplus should be defined to 199711L but many compilers define it to 1.

To allow for these differences, users should define macros such as STDC and __cplusplus in System Macro Defines to the values of their compiler.

Some examples:

Proposal:

wenns commented 10 years ago

Thanks for the excellent research and precise explanation.

It makes sense. Nevertheless, Im somewhat divided on this because:

So there are pros and cons...

guwirth commented 10 years ago

Mainstream means:

So I think there is no 'one fits all'.

I see different possibilities:

I would tend to the first solution, is at the end the easiest.

wenns commented 10 years ago

On 12/16/2013 09:07 AM, Günter Wirth wrote:

Mainstream means:

  • GNU * C: FILE , LINE , DATE , TIME , STDC , _STDCVERSION , _STDCHOSTED * C++: FILE , LINE , DATE , TIME , __cplusplus
  • Visual Studio
  • C: FILE , LINE , DATE , TIME, TIMESTAMP , STDC *

    C++: FILE , LINE , DATE , TIME, TIMESTAMP , __cplusplus

    *

    _STDCVERSION: The value 199409L signifies the 1989 C standard; the value 199901L signifies the 1999 revision of the C standard; and 201112L for 2011 C standard

  • __cplusplus: Depending on the language standard selected, the value of the macro is 199711L, as mandated by the 1998 C++ standard; 201103L, per the 2011 C++ standard

So I think there is no 'one fits all'.

I see different possibilities:

  • Define only the intersection (FILE , LINE , DATE , TIME) and rest must be defined by user. And yes: user need some knowledge about settings. But on the other hand these settings are only a small subset of the things users has to define (see links above).
  • Try to predefine everything to the best of knowledge. Here the critical point is that users can't remove some of your predefined values afterwards. For this case some kind of undef is needed (see cppcheck -U).
  • Third possibility is to add a switch: c89, c99, c11, c++98 or c++03, c++11 (see cppcheck --std).

I would tend to the first solution, is at the end the easiest.

I dont object if we get more precise here and replace the current lazy implementation. I tend to the third option, however, as its more commonly found implemented in other tools (cppcheck, SonarSource C++). Besides the standard predefined macros, we will probably need this switch when dealing with grammars changes in the future anyway.

BTW: Did you use the plugin to analyze substantial code bases in C? We do not target C explicitly, the plugin implements the grammar from the C++11 standard.

— Reply to this email directly or view it on GitHub https://github.com/wenns/sonar-cxx/issues/86#issuecomment-30642581.

guwirth commented 10 years ago

BTW: Did you use the plugin to analyze substantial code bases in C?

No only C++. I'm also using still V0.2 because I'm getting to much errors with V0.9.

guwirth commented 10 years ago

Example for VS10, 32bit settings:

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @TODO: Add your preprocessor definitions here (Project\Properties\Configuration Properties\C/C++\Preprocessor).
//        Have also a look to the 'Inherited values' (Edit\Inherited values)!
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 1) Is your project an application (none), a DLL(_DLL) or a static library (_LIB)?
#define _DLL 1
//#define _LIB 1

// 2) Is your project a Windows (_WINDOWS) or Console (_CONSOLE) application?
#define _WINDOWS 1
//#define _CONSOLE 1

// 3) Does your project use Unicode (UNICODE) or Multi-Byte (_MBCS) character set
#define UNICODE 1
#define _UNICODE 1
//#define _MBCS 1

// 4) Are you using the MFC?
//    Build Settings for an MFC DLL
//    - Regular, statically linked to MFC: _WINDLL, _USRDLL
//    - Regular, using the shared MFC DLL: _WINDLL, _USRDLL, _AFXDLL
//    - Extension DLL: _WINDLL, _AFXDLL, _AFXEXT
//#define _WINDLL 1
//#define _USRDLL 1
#define _AFXDLL 1
//#define _AFXEXT 1

// 5) Are you using the ATL?
//    - Dynamic Link to ATL: _ATL_DLL
//    - Static Link to ATL: _ATL_STATIC_REGISTRY
#define _ATL_DLL 1
//#define _ATL_STATIC_REGISTRY 1

// 6) Add your other preprocessor definitions here
// ...

// disable assert for production version
#define NDEBUG 1

// STRICT Type Checking: 
#define STRICT 1

// Defines the MFC version.
#if defined(_AFXDLL) || defined(_USRDLL)
#define _MFC_VER 0x0A00
#endif

// Defines the ATL version.
#if defined(_ATL_DLL) || defined(_ATL_STATIC_REGISTRY) || defined(_MFC_VER)
#define _ATL_VER 0x0A00
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CXX plugin Predefined Macros V0.9
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//#define __DATE__ "??? ?? ????"
//#define __FILE__ "file"
//#define __LINE__ 1
//#define __TIME__ "??:??:??"
//#define __cplusplus 1
#undef __cplusplus
//#define __STDC__ 1
#undef __STDC__
//#define __STDC_HOSTED__ 1
#undef __STDC_HOSTED__

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ANSI-Compliant Predefined Macros
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// The compilation date of the current source file. The date is a string literal
// of the form Mmm dd yyyy. The month name Mmm is the same as for dates generated
// by the library function asctime declared in TIME.H.
//#define __DATE__ "??? ?? ????"

// The name of the current source file. __FILE__ expands to a string surrounded
// by double quotation marks. To ensure that the full path to the file is
// displayed, use /FC (Full Path of Source Code File in Diagnostics). 
//#define __FILE__ "file"

// The line number in the current source file. The line number is a decimal
// integer constant. It can be changed with a #line directive. 
//#define __LINE__ 1

// Indicates full conformance with the ANSI C standard. Defined as the integer
// constant 1 only if the /Za compiler option is given and you are not compiling
// C++ code; otherwise is undefined. 
//#define __STDC__ 1

// The most recent compilation time of the current source file. The time is a
// string literal of the form hh:mm:ss. 
//#define __TIME__ "??:??:??"

// The date and time of the last modification of the current source file,
// expressed as a string literal in the form Ddd Mmm Date hh:mm:ss yyyy, where
// Ddd is the abbreviated day of the week and Date is an integer from 1 to 31.
#define __TIMESTAMP__ __DATE__ __TIME__

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Microsoft-Specific Predefined Macros
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Defined when /arch:AVX is specified.
//#define __AVX__ 

// Default char type is unsigned. Defined when /J is specified. 
//#define _CHAR_UNSIGNED 1

// Defines the version of the common language runtime used when the application
// was compiled. 
//#define __CLR_VER 

// Defined when you compile with /clr, /clr:pure, or /clr:safe.
//#define __cplusplus_cli 200406

// Defined when you use the /ZW option to compile.
//#define __cplusplus_winrt 201009

// Expands to an integer starting with 0 and incrementing by 1 every time it is
// used in a source file or included headers of the source file.
#define __COUNTER__ __LINE__

// Defined for C++ programs only.
#define __cplusplus 199711L

// Defined for code compiled with /GR (Enable Run-Time Type Information).
#define _CPPRTTI 1

// Defined for code compiled by using one of the /EH (Exception Handling Model) flags.
#define _CPPUNWIND 1

// Defined when you compile with /LDd, /MDd, and /MTd.
//#define _DEBUG 1

// Valid only in a function. Defines the undecorated name of the enclosing function as a string.
#define __FUNCTION__ "function"
#define __FUNCTIONW__ L"function"

// Valid only in a function. Defines the decorated name of the enclosing function as a string.
#define __FUNCDNAME__ __FUNCTION__

// Valid only in a function. Defines the signature of the enclosing function as a string.
// __FUNCSIG__ is not expanded if you use the /EP or /P compiler option.
// On a 64-bit operating system, the calling convention is __cdecl by default.
#define __FUNCSIG__ __FUNCTION__

// Reports the maximum size (in bits) for an integral type.
#define _INTEGRAL_MAX_BITS 64

// Defined for DEC ALPHA platforms (no longer supported).
//#define _M_ALPHA 

// Defined for x64 processors.
//#define _M_AMD64 

// Defined for a compilation that uses any form of /clr (/clr:oldSyntax, /clr:safe, for example).
//#define _M_CEE 

// Defined for a compilation that uses /clr:pure.
//#define _M_CEE_PURE 

// Defined for a compilation that uses /clr:safe.
//#define _M_CEE_SAFE 

// Defined for x86 processors. See the Values for _M_IX86 table below for more
// information. This is not defined for x64 processors.
#define _M_IX86 600

// Defined for Itanium Processor Family 64-bit processors.
//#define _M_IA64 

// Expands to a value indicating which /arch compiler option was used.
//#define _M_ARM_FP 

// Expands to a value indicating which /arch compiler option was used.
#define _M_IX86_FP 0

// Defined for Power Macintosh platforms (no longer supported).
//#define _M_MPPC 

// Defined for MIPS platforms (no longer supported).
//#define _M_MRX000 

// Defined for PowerPC platforms (no longer supported).
//#define _M_PPC 

// Defined for x64 processors.
//#define _M_X64 

// Defined to be 1 when /clr is specified.
//#define _MANAGED 1

// Evaluates to the revision number component of the compiler's version number.
// The revision number is the fourth component of the period-delimited version number.
// For example, if the version number of the Visual C++ compiler is 15.00.20706.01,
// the _MSC_BUILD macro evaluates to 1.
#define _MSC_BUILD 1

// This macro is defined when you compile with the /Ze compiler option (the default).
// Its value, when defined, is 1.
#define _MSC_EXTENSIONS 1

// Evaluates to the major, minor, and build number components of the compiler's version number.
#define _MSC_FULL_VER 160040219

// Evaluates to the major and minor number components of the compiler's version number. 
#define _MSC_VER 1600

// Defined when one of the /RTC compiler options is specified.
#define __MSVC_RUNTIME_CHECKS 1

// Defined when /MD or /MDd (Multithreaded DLL) or /MT or /MTd (Multithreaded) is specified.
#define _MT 1

// Defined when /Zc:wchar_t is used.
#define _NATIVE_WCHAR_T_DEFINED 1

// Defined when compiling with /openmp, returns an integer representing
// the date of the OpenMP specification implemented by Visual C++.
//#define _OPENMP 200203

// Defined when /Zl is used; see /Zl (Omit Default Library Name) for more information.
//#define _VC_NODEFAULTLIB 

// Defined when /Zc:wchar_t is used or if wchar_t is defined in a system header file
// included in your project.
#define _WCHAR_T_DEFINED 1

// Determines the minimum platform SDK required to build your application.
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#define NTDDI_VERSION 0x06000000

// Defined for applications for Win32 and Win64. Always defined.
#define WIN32 1
#define _WIN32 1
#define __WIN32 1

// Defined for applications for Win64.
//#define _WIN64 

// Defined when specifying /Wp64.
//#define _Wp64 

// makers for documenting the semantics of APIs (sal.h)
#define _USE_DECLSPECS_FOR_SAL 0
//#define SAL_NO_ATTRIBUTE_DECLARATIONS
Bertk commented 10 years ago

Maybe you want to check the PC-lint solution for MSVC to create project related definitions (file mac-msc.cpp). I use this approach for code analysis using PC-lint. Unfortunately this is not available for the other supported compilers (gcc, intel, …)

guwirth commented 8 years ago

Seems to be no use for this.