Question

In: Computer Science

A pragma and an intrinsic function are both statements embedded in C source code. What is...

A pragma and an intrinsic function are both statements embedded in C source code. What is the primary difference in how the compiler handles these two types statements?

Solutions

Expert Solution

Detailed explanation of Pragma on compilers :

The ‘#pragma’ directive is the method specified by the C standard for providing additional information to the compiler, beyond what is conveyed in the language itself. The forms of this directive (commonly known as pragmas) specified by C standard are prefixed with STDC. A C compiler is free to attach any meaning it likes to other pragmas. Most GNU-defined, supported pragmas have been given a GCC prefix.

C99 introduced the _Pragma operator. This feature addresses a major problem with ‘#pragma’: being a directive, it cannot be produced as the result of macro expansion. _Pragma is an operator, much like sizeofor defined, and can be embedded in a macro.

Its syntax is _Pragma (string-literal), where string-literal can be either a normal or wide-character string literal. It is destringized, by replacing all ‘\\’ with a single ‘\’ and all ‘\"’ with a ‘"’. The result is then processed as if it had appeared as the right hand side of a ‘#pragma’ directive. For example,

_Pragma ("GCC dependency \"parse.y\"")

has the same effect as #pragma GCC dependency "parse.y". The same effect could be achieved using macros, for example

#define DO_PRAGMA(x) _Pragma (#x)
DO_PRAGMA (GCC dependency "parse.y")

The standard is unclear on where a _Pragma operator can appear. The preprocessor does not accept it within a preprocessing conditional directive like ‘#if’. To be safe, you are probably best keeping it out of directives other than ‘#define’, and putting it on a line of its own.

This manual documents the pragmas which are meaningful to the preprocessor itself. Other pragmas are meaningful to the C or C++ compilers. They are documented in the GCC manual.

GCC plugins may provide their own pragmas.

#pragma GCC dependency

#pragma GCC dependency allows you to check the relative dates of the current file and another file. If the other file is more recent than the current file, a warning is issued. This is useful if the current file is derived from the other file, and should be regenerated. The other file is searched for using the normal include search path. Optional trailing text can be used to give more information in the warning message.

#pragma GCC dependency "parse.y"
#pragma GCC dependency "/usr/include/time.h" rerun fixincludes

#pragma GCC poison

Sometimes, there is an identifier that you want to remove completely from your program, and make sure that it never creeps back in. To enforce this, you can poison the identifier with this pragma.#pragma GCC poison is followed by a list of identifiers to poison. If any of those identifiers appears anywhere in the source after the directive, it is a hard error. For example,

#pragma GCC poison printf sprintf fprintf
sprintf(some_string, "hello");

will produce an error.

If a poisoned identifier appears as part of the expansion of a macro which was defined before the identifier was poisoned, it will not cause an error. This lets you poison an identifier without worrying about system headers defining macros that use it.

For example,

#define strrchr rindex
#pragma GCC poison rindex
strrchr(some_string, 'h');

will not produce an error.

#pragma GCC system_header

This pragma takes no arguments. It causes the rest of the code in the current file to be treated as if it came from a system header. See System Headers.

#pragma GCC warning

#pragma GCC error

#pragma GCC warning "message" causes the preprocessor to issue a warning diagnostic with the text ‘message’. The message contained in the pragma must be a single string literal. Similarly, #pragma GCC error "message" issues an error message. Unlike the ‘#warning’ and ‘#error’ directives, these pragmas can be embedded in preprocessor macros using ‘_Pragma’.

#pragma once

If #pragma once is seen when scanning a header file, that file will never be read again, no matter what. It is a less-portable alternative to using ‘#ifndef’ to guard the contents of header files against multiple inclusions.

Pragma Directives and the __Pragma Keyword:

Pragma directives specify machine- or operating-specific compiler features. The __pragma keyword, which is specific to the Microsoft compiler, enables you to code pragma directives within macro definitions.

Syntax

#pragma token-string
__pragma(token-string)

Remarks

Each implementation of C and C++ supports some features unique to its host machine or operating system. Some programs, for example, must exercise precise control over the memory areas where data is put or to control the way certain functions receive parameters. The #pragma directives offer a way for each compiler to offer machine- and operating system-specific features while retaining overall compatibility with the C and C++ languages.

Pragmas are machine- or operating system-specific by definition, and are usually different for every compiler. Pragmas can be used in conditional statements, to provide new preprocessor functionality, or to provide implementation-defined information to the compiler.

The token-string is a series of characters that gives a specific compiler instruction and arguments, if any. The number sign (#) must be the first non-white-space character on the line that contains the pragma; white-space characters can separate the number sign and the word "pragma". Following #pragma, write any text that the translator can parse as preprocessing tokens. The argument to #pragma is subject to macro expansion.

If the compiler finds a pragma that it does not recognize, it issues a warning and continues compilation.

The Microsoft C compilers recognize the following pragmas:

alloc_text auto_inline bss_seg
check_stack code_seg comment
component const_seg
data_seg deprecated detect_mismatch
fenv_access float_control fp_contract
function hdrstop include_alias
inline_depth inline_recursion
intrinsic make_public
managed message
omp once
optimize pack
pop_macro push_macro region, endregion
runtime_checks section setlocale
strict_gs_check unmanaged
warning

Pragmas and Compiler Options :

Some pragmas provide the same functionality as compiler options. When a pragma is encountered in source code, it overrides the behavior specified by the compiler option. For example, if you specified /Zp8, you can override this compiler setting for specific sections of the code with pack:

cl /Zp8 ...

<file> - packing is 8
// ...
#pragma pack(push, 1) - packing is now 1
// ...
#pragma pack(pop) - packing is 8
</file>

The __pragma() Keyword

Microsoft specific

The compiler also supports the __pragma keyword, which has the same functionality as the #pragma directive, but can be used inline in a macro definition. The #pragma directive cannot be used in a macro definition because the compiler interprets the number sign character ('#') in the directive to be the stringizing operator (#).

Intrinsics on compiler :

Most functions are contained in libraries, but some functions are built in (that is, intrinsic) to the compiler. These are referred to as intrinsic functions or intrinsics.

Remarks

If a function is an intrinsic, the code for that function is usually inserted inline, avoiding the overhead of a function call and allowing highly efficient machine instructions to be emitted for that function. An intrinsic is often faster than the equivalent inline assembly, because the optimizer has a built-in knowledge of how many intrinsics behave, so some optimizations can be available that are not available when inline assembly is used. Also, the optimizer can expand the intrinsic differently, align buffers differently, or make other adjustments depending on the context and arguments of the call.

The use of intrinsics affects the portability of code, because intrinsics that are available in Visual C++ might not be available if the code is compiled with other compilers and some intrinsics that might be available for some target architectures are not available for all architectures. However, intrinsics are usually more portable than inline assembly. The intrinsics are required on 64-bit architectures where inline assembly is not supported.

Some intrinsics, such as __assume and __ReadWriteBarrier, provide information to the compiler, which affects the behavior of the optimizer.

Some intrinsics are available only as intrinsics, and some are available both in function and intrinsic implementations. You can instruct the compiler to use the intrinsic implementation in one of two ways, depending on whether you want to enable only specific functions or you want to enable all intrinsics. The first way is to use #pragma intrinsic(intrinsic-function-name-list). The pragma can be used to specify a single intrinsic or multiple intrinsics separated by commas. The second is to use the /Oi (Generate Intrinsic Functions) compiler option, which makes all intrinsics on a given platform available. Under /Oi, use #pragma function(intrinsic-function-name-list) to force a function call to be used instead of an intrinsic. If the documentation for a specific intrinsic notes that the routine is only available as an intrinsic, then the intrinsic implementation is used regardless of whether /Oi or #pragma intrinsic is specified. In all cases, /Oi or #pragma intrinsic allows, but does not force, the optimizer to use the intrinsic. The optimizer can still call the function.

Some standard C/C++ library functions are available in intrinsic implementations on some architectures. When calling a CRT function, the intrinsic implementation is used if /Oi is specified on the command line.

A header file, <intrin.h>, is available that declares prototypes for the common intrinsic functions. Manufacturer-specific intrinsics are available in the <immintrin.h> and <ammintrin.h> header files. Additionally, certain Windows headers declare functions that map onto a compiler intrinsic.


Related Solutions

Which of the following statements is not true about intrinsic pathway of apoptosis: a) Cytochrome c...
Which of the following statements is not true about intrinsic pathway of apoptosis: a) Cytochrome c release into the cytosol leads to METC uncoupling and superoxide production b) Activation of death receptors by ligands c) Activates initiator and executioner caspases d) Involves cytochrome c release after oxidative insult e) Apoptosome could induce caspase-9 dimerization
This problem needs to be solved with source code. I need a C++ program that will...
This problem needs to be solved with source code. I need a C++ program that will help me solve this question. I need it in C++, please. Writing with comments so it maybe cleared. 1.2. We received the following ciphertext which was encoded with a shift cipher: xultpaajcxitltlxaarpjhtiwtgxktghidhipxciwtvgtpilpit ghlxiwiwtxgqadds. 1. Perform an attack against the cipher based on a letter frequency count: How many letters do you have to identify through a frequency count to recover the key? What is...
C++ Write the C++ code for a void function that prompts the user to enter a...
C++ Write the C++ code for a void function that prompts the user to enter a name, and then stores the user's response in the string variable whose address is passed to the function. Name the function getName.
Write source code in C to simulate the contiguous file allocation with the following conditions: •...
Write source code in C to simulate the contiguous file allocation with the following conditions: • Prompt the user to ender the no of files • Enter the name of the file • Enter the Starting block number • Enter no of block occupied by the file i.Condition: No two files must have the same block(if the user enter the same block no present in the previous file prompt the user “Block already in use”) #include<stdio.h> #include<conio.h> struct {    ...
Windows Interprocess communication. WM_CopyData IPC (data copy) - source code (c++) windows data copy IPC code
Windows Interprocess communication. WM_CopyData IPC (data copy) - source code (c++) windows data copy IPC code
why source code repositories are critical to cloud computing. Why are source code repositories a better...
why source code repositories are critical to cloud computing. Why are source code repositories a better approach than other past methods?  
Write an x86 assembly language program that performs equivalently to the C++ source code file shown...
Write an x86 assembly language program that performs equivalently to the C++ source code file shown below.Please note that commented out behavior must be implemented in x86 assembly language. There is no standard, portable way to perform some of these actions in C++. #include void main() { // Use registers for these in your x86 assembly language program // Only use the .data segment for string (character array) variables int eax; int esi; int ecx; int edi; // Loop the...
*Code in C* Write a function that checks if a number is a perfect cube. Write...
*Code in C* Write a function that checks if a number is a perfect cube. Write another function that calculates the integer cubic root. Under the main program: Prompt the user to input a number Tell the user if the number is a perfect cube or not Print the cubic root if the inputted number is a perfect cube.
Code needed in C++ (nOT IN STEP BY STEP EITHER)    Write a recursive function that...
Code needed in C++ (nOT IN STEP BY STEP EITHER)    Write a recursive function that computes the sum of the digits in an integer. Use the following function header: int sumDigits(int n) For example, sumDigits(234) returns 2 + 3 + 4 = 9. Write a test program that prompts the user to enter an integer and displays its sum.
Translate the C function code below to the MIPS True Assembler Language code (machine instructions only)....
Translate the C function code below to the MIPS True Assembler Language code (machine instructions only). The function code should follow the conventions for MIPS function calls including passing parameters and returning results. Your function code must be written with the minimum number of machine instructions to be executed and without any use of MIPS pseudo-instructions. Myfunction(unsigned int a, unsigned int b, unsigned int c) { int i=0; while (a > c) { a /= b; i++; } return i;...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT