Value of Type 'Tags' Has No Member 'Lastused'

Value of type 'Tags' has no member 'lastUsed'

The problem is that the declarations of name and lastUsed have an invisible character (U+200B = "ZERO WIDTH SPACE") as the last character of the identifier.

Here is a short example demonstrating what seems to be a paradox. The first print statement does not compile, but the last one does:

struct Tags {
let name​ = "name"
}

print(Tags().name) // (1) Error: Value of type 'Foo' has no member 'name'
print(Tags().name​) // (2) No error

Unfortunately, Xcode does not display this character, even if “Editor->Invisibles” is switched on. Opening the file in vi shows the issue:

struct Tags {
let name<200b> = "name"
}

print(Tags().name) // (1) Error: Value of type 'Foo' has no member 'name'
print(Tags().name<200b>) // (2) No error

Note that invisible characters are allowed in identifier names, this has been discussed in the Swift forum.

The first print statement was created with Xcode's code completion and Xcode omits the trailing invisible character. I would consider that a bug.

The second print statement was created by carefully copying the name​ identifier including the trailing invisible character.

Summary: Swift identifiers can contain invisible characters, but those do not work well with Xcode's code completion and cause only confusion. Rewriting all occurrences of those identifiers fixes the issue.

Value of type 'ARFrame' has no member 'viewTrans'

ARFrame doesn't have any viewTrans method:
https://developer.apple.com/documentation/arkit/arframe

Instead you should change this line:

self.viewTrans = frame.viewTrans(for: UIInterfaceOrientation.portrait, viewportSize: targetSize)

To this:

self.viewTrans = frame.displayTransform(for: UIInterfaceOrientation.portrait, viewportSize: targetSize)

displayTransform(for:viewportSize:)
Returns an affine transform for converting between normalized image coordinates and a coordinate space appropriate for rendering the camera image onscreen.

See here: https://developer.apple.com/documentation/arkit/arframe/2923543-displaytransform

C struct called in Swift not being updated when it calls native code

Is the copy of the struct invoked from Swift different from the one being used by C?

Exactly. This

let fs: FastSax = ptr!.withMemoryRebound(to: FastSax.self, capacity: 1) {
$0.pointee
}

is a (complicated) way of making a copy of the struct pointed to by ptr. Then

let out = fs.parse(ptr , line)

updates the structure pointed to by ptr (which is the default structure obtained before) and not the structure pointed to by fs.

What you probably want is simply

let out = fastSax!.pointee.parse(fastSax, line)

assuming that fastSax is not nil. Use optional binding or optional chaining if that is not guaranteed. The ptr and fs variables are not needed.

Select count(col_name) in sqlite (Swift) not working

The column numbers when returning values (e.g. the result of sqlite3_column_xxx) are zero-based. You’re attempting to retrieve column 1, when you meant column 0.


By the way, if you want to detect invalid index, you can remove that nil coalescing operator. E.g., so, instead of:

if try stmt.step() == .row {
return Int(from: stmt,index: 1) ?? -1
}

You could instead check to see if not only if step succeeded, but also that Int(from:index:) returned a non-nil value:

if try stmt.step() == .row {
if let count = Int(from: stmt, index: 1) {
return count
} else {
// do whatever you want when it fails, e.g.

fatalError("no value returned; invalid column index?")
}
}

Or perhaps more succinctly:

if try stmt.step() == .row, let count = Int(from: stmt, index: 1) {
return count
} else {
fatalError("no value returned; invalid column index?")
}

That would lead you to recognize that you need the 0-based index:

if try stmt.step() == .row, let count = Int(from: stmt, index: 0) {
return count
} else {
fatalError("no value returned; invalid column index?")
}

C union member gives particular/wrong value when other member is set to a new value. Why is this output in following code in C?

As you are already aware that union shares memory location between the members inside. In case of union compiler allocated the memory equal to the max size of the member and use the same memory for all the members.

Hence when you execute data.f=220.5;, shared memory location between i and f holding data.i=20; got overwritten to a new value (220.5) with binary representation as follows :

Sample Image

Now again, when this value is read as a signed integer int it will be interpreted without conversion as 1130135552 in decimal representation. Hence you are getting 1130135552.

Further if you want to use all members of union, then struct is the answer.

struct Data
{
char str[20];
int i;
float f;
} data;

data.i=20;
data.f=220.5;
printf("%d\n",data.i);

For more information on union and struct Please refer the following from Difference between Structure and Union:
Sample Image

Union members of the same type

Yes, that's fine.

The standard (C11 draft) says:

[...] if a union contains several structures that share a common initial
sequence (see below), and if the union object currently contains one of
these structures, it is permitted to inspect the common initial part of any
of them anywhere that a declaration of the completed type of the union is
visible

Here the two integers can be considered to be (very simple) structures that share the same initial sequence.

Even ignoring that, there's also:

If the member used to read the contents of a union object is not the same
as the member last used to store a value in the object, the appropriate
part of the object representation of the value is reinterpreted as an
object representation in the new type

Reinterpreting an int as an int is pretty safe. :)

Is the following C union access pattern undefined behavior?

Defect report 283: Accessing a non-current union member ("type punning") covers this and tells us there is undefined behavior if there is trap representation.

The defect report asked:

In the paragraph corresponding to 6.5.2.3#5, C89 contained this
sentence:

With one exception, if a member of a union object is accessed after a value has been stored in a different member of the object, the
behavior is implementation-defined.


Associated with that sentence was this footnote:

The "byte orders" for scalar types are invisible to isolated programs that do not indulge in type punning (for example, by
assigning to one member of a union and inspecting the storage by
accessing another member that is an appropriately sixed array of
character type), but must be accounted for when conforming to
externally imposed storage layouts.


The only corresponding verbiage in C99 is 6.2.6.1#7:

When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that
member but do correspond to other members take unspecified values, but
the value of the union object shall not thereby become a trap
representation.


It is not perfectly clear that the C99 words have the same
implications as the C89 words.

The defect report added the following footnote:

Attach a new footnote 78a to the words "named member" in 6.5.2.3#3:

78a If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.

C11 6.2.6.1 General tells us:

Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined.50) Such a representation is called a trap representation.

Accessing inactive union member and undefined behavior?

The confusion is that C explicitly permits type-punning through a union, whereas C++ (c++11) has no such permission.

c11

6.5.2.3 Structure and union members


95) If the member used to read the contents of a union object is not the same as the member last used to
store a value in the object, the appropriate part of the object representation of the value is reinterpreted
as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type
punning’’). This might be a trap representation.

The situation with C++:

c++11

9.5 Unions [class.union]


In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time.

C++ later has language permitting the use of unions containing structs with common initial sequences; this doesn't however permit type-punning.

To determine whether union type-punning is allowed in C++, we have to search further. Recall that c99 is a normative reference for C++11 (and C99 has similar language to C11 permitting union type-punning):

3.9 Types [basic.types]


4 - The object representation of an object of type T is the sequence of N unsigned char objects taken up by
the object of type T, where N equals sizeof(T). The value representation of an object is the set of bits that
hold the value of type T. For trivially copyable types, the value representation is a set of bits in the object
representation that determines a value, which is one discrete element of an implementation-defined set of
values. 42

42) The intent is that the memory model of C++ is compatible with that of ISO/IEC 9899 Programming Language C.

It gets particularly interesting when we read

3.8 Object lifetime [basic.life]


The lifetime of an object of type T begins when:
— storage with the proper alignment and size for type T is obtained, and
— if the object has non-trivial initialization, its initialization is complete.

So for a primitive type (which ipso facto has trivial initialization) contained in a union, the lifetime of the object encompasses at least the lifetime of the union itself. This allows us to invoke

3.9.2 Compound types [basic.compound]


If an object of type T is located at an address A, a pointer of type cv T* whose value is the
address A is said to point to that object, regardless of how the value was obtained.

Assuming that the operation we are interested in is type-punning i.e. taking the value of a non-active union member, and given per the above that we have a valid reference to the object referred to by that member, that operation is lvalue-to-rvalue conversion:

4.1 Lvalue-to-rvalue conversion [conv.lval]


A glvalue of a non-function, non-array type T can be converted to a prvalue.
If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.

The question then is whether an object that is a non-active union member is initialized by storage to the active union member. As far as I can tell, this is not the case and so although if:

  • a union is copied into char array storage and back (3.9:2), or
  • a union is bytewise copied to another union of the same type (3.9:3), or
  • a union is accessed across language boundaries by a program element conforming to ISO/IEC 9899 (so far as that is defined) (3.9:4 note 42), then

the access to a union by a non-active member is defined and is defined to follow the object and value representation, access without one of the above interpositions is undefined behaviour. This has implications for the optimisations allowed to be performed on such a program, as the implementation may of course assume that undefined behaviour does not occur.

That is, although we can legitimately form an lvalue to a non-active union member (which is why assigning to a non-active member without construction is ok) it is considered to be uninitialized.



Related Topics



Leave a reply



Submit