What Is a Scalar Object in C++

What is a scalar Object in C++?

Short version: Types in C++ are:

  • Object types: scalars, arrays, classes, unions

  • Reference types

  • Function types

  • (Member types) [see below]

  • void


Long version

  • Object types

    • Scalars

      1. arithmetic (integral, float)

      2. pointers: T * for any type T

      3. enum

      4. pointer-to-member

      5. nullptr_t

    • Arrays: T[] or T[N] for any complete, non-reference type T

    • Classes: class Foo or struct Bar

      1. Trivial classes

      2. Aggregates

      3. POD classes

      4. (etc. etc.)

    • Unions: union Zip

  • References types: T &, T && for any object or free-function type T

  • Function types

    • Free functions: R foo(Arg1, Arg2, ...)

    • Member functions: R T::foo(Arg1, Arg2, ...)

  • void

Member types work like this. A member type is of the form T::U, but you can't have objects or variables of member type. You can only have member pointers. A member pointer has type T::* U, and it is a pointer-to-member-object if U is a (free) object type, and a pointer-to-member-function if U is a (free) function type.

All types are complete except void, unsized arrays and declared-but-not-defined classes and unions. All incomplete types except void can be completed.

All types can be const/volatile qualified.

The <type_traits> header provides trait classes to check for each of these type characteristics.

What is the purpose of a scalar in the C++ type traits sense?

One purpose is to write more efficient template specializations. On many architectures, it would be more efficient to pass around pointers to objects than to copy them, but scalars can fit into registers and be copied with a single machine instruction. Or a generic type might need locking, while the machine guarantees that it will read or update a properly-aligned scalar with a single atomic instruction.

Scalar vs. primitive data type - are they the same thing?

I don't think they're interchangeable. They are frequently similar, but differences do exist, and seems to mainly be in what they are contrasted with and what is relevant in context.

Scalars are typically contrasted with compounds, such as arrays, maps, sets, structs, etc. A scalar is a "single" value - integer, boolean, perhaps a string - while a compound is made up of multiple scalars (and possibly references to other compounds). "Scalar" is used in contexts where the relevant distinction is between single/simple/atomic values and compound values.

Primitive types, however, are contrasted with e.g. reference types, and are used when the relevant distinction is "Is this directly a value, or is it a reference to something that contains the real value?", as in Java's primitive types vs. references. I see this as a somewhat lower-level distinction than scalar/compound, but not quite.

It really depends on context (and frequently what language family is being discussed). To take one, possibly pathological, example: strings. In C, a string is a compound (an array of characters), while in Perl, a string is a scalar. In Java, a string is an object (or reference type). In Python, everything is (conceptually) an object/reference type, including strings (and numbers).

Is b a scalar object in this case?

Quote from ISO/IEC 9899:2018 (C18), 6.2.5 (Types)/21:

"Arithmetic types and pointer types are collectively called scalar types. Array and structure types are collectively called aggregate types.47)"

47) "Note that aggregate type does not include union type because an object with union type can only contain one member at a time."


"What is the exact definition of a scalar object?"

A scalar object is an object which only consists of a single entity, such as pointers and objects of arithmetic types.

"Is b a scalar object in this case?"

b isn´t a scalar object as a scalar object hold only one single entity. Arrays such as b are "aggregates". The array to pointer decay in scanf("%4s%4s", b, b); and printf("%s", b); doesn´t change that b is still of array type.

The scalar type additionnal in C++

In C++ the scalar types are (6.7 Types)

9 Arithmetic types (6.7.1), enumeration types, pointer types,
pointer-to-member types (6.7.2), std::nullptr_t, and cv-qualified
(6.7.3) versions of these types are collectively called scalar types.

In C the scalar types are (6.2.5 Types)

21 Arithmetic types and pointer types are collectively called scalar
types.

Pay attention to that in C

11 There are three complex types, designated as float _Complex, double
_Complex, and long double _Complex. 43) (Complex types are a conditional feature
that implementations need not support; see
6.10.8.3.) The real floating and complex types are collectively called the
floating types

In C++ complex types are user-defined types that is they are defined as classes.

Also in C enumerations are included in the category of the arithmetic types while in C++ enumerations are not included in the category of arithmetic types.

And in C there is standard unsigned integer type _Bool while in C++ it is absent. On the other hand, in C++ there is the integral type bool that is absent in C.

Is void a scalar type?

The type void is not considered a scalar type. It is actually an incomplete type.

Section 6.2.5 of the C standard regarding "Types" states the following regarding void in paragraph 19:

The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.

And paragraph 21 defines scalar types as:

Arithmetic types and pointer types are collectively called scalar types. Array and structure types are collectively called
aggregate types.

Is there a difference between the terms scalar and primitive in Objective-C?

As far as I understand that linked documentation, scalars is data that is one slot of memory large, where a slot may be 1, 2, 4,… bytes. The number of bytes is defined by the architecture of the processor, the compiler and variable type.

The term primitives seem to include also arrays of any of this types and pointers to scalars.

It is not clear if C structures are seen as primitives or not.

from a Objective-C programer's perspective you could define: If it is an pointer to an instance of a class, it is an object, else a C primitive (structs included). Further if I need to use a wrapper object of NSNumber, to store it in NSArray, it is a scalar.

scalar object requires one element in initializer

uint8_t *mmac_source1 = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x01 }; 

Here you don't memory allocated to the pointer.
mmac_source1 just acts as a place holder wherein you can store an address.

uint8_t mmac_source1[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x01 };

Here you have an array where in your compiler allocates sizof(uint8_t)*6 bytes.

C - only scalar operations?

Given the context and topic of the article, what the article is referring to is the term "scalar" as it is defined in C language itself. In C language arithmetic types and pointer types together are called scalar types (see 6.2.5/21). In everyday language we often see these types referred to as basic types or built-in types (while the proper formal term is, again, scalar). The point is that scalar types are intended to be the types that are immediately (or almost immediately) supported by hardware. Most non-conceptual operations in C operate on scalar types and scalar types only.

If you take a look at the history of C language, you'll see that early versions of C were so restrictively scalar, that you couldn't even assign one struct object to another struct object (or pass it to a function/return from a function by value). The ability do the struct copying in the core language was added to C later. And to this day it remains essentially the only non-scalar operation in the entire core language.

C++, on the other hand, as well as other higher-level languages, supports operations on user-defined types, which are by definition not scalar, or on other types that have no immediate support from hardware.

P.S. No, the point the article is trying to make has nothing to do with vector operations, as opposed to scalar operations. Support for vector operations is, of course, completely orthogonal to the level of the language. You can have vector operations in low-level languages as well as in high-level languages. The term scalar is used in a sense that I described above.



Related Topics



Leave a reply



Submit