Using 'override' for a function that has been declared using 'typedef'

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
15
down vote

favorite
1












C++ 11 introduced the 'override' specifier for functions and I find it useful as it makes it explicit that a virtual function is being overridden. However, I can't seem to get it work for a function that has been declared using a typedef.



I understand that 'override' is not a keyword, has it got something to do with that?



The following code illustrates my point:



#include <iostream>

typedef char ReturnsChar();

class Basic

public:
virtual char get_a();
virtual ReturnsChar get_z;
;

char Basic::get_a() return 'a';
char Basic::get_z() return 'z';

class Capitalized : public Basic

public:
// Can override explicitly if I use the normal definition
char get_a() override;

// Compiles if I use the typedef but not 'override'
ReturnsChar get_z;

// Will not compile, but would like to do this
//ReturnsChar get_z override;

;

char Capitalized::get_a() return 'A';
char Capitalized::get_z() return 'Z';

int main()

Basic foo;
Capitalized bar;

std::cout << foo.get_a() << std::endl; // a
std::cout << foo.get_z() << std::endl; // z
std::cout << bar.get_a() << std::endl; // A
std::cout << bar.get_z() << std::endl; // Z



I'm using GNU's g++ 8.2.0 and the error it gives me is




error: expected ';' at end of member declaration
ReturnsChar get_z override;
^~~~~
;
error: ‘override’ does not name a type; did you mean ‘ctermid’?
ReturnsChar get_z override;
^~~~~~~~
ctermid



EDIT: To address the comments, I understand this style is unclear. I am more interested about why this won't compile and what exactly 'override' does (especially because it is not a keyword).
As an aside, I feel like typedef-ing functions might be clear in some cases, say:



void (*foo(int x, void (*f)(int)))(int);


That's hard to read, especially if comes up often. I can just typedef that as 'UpdateAddressFunction' and then mentally think of every function of that type as something that 'updates an address'.










share|improve this question



















  • 9




    That is a really confusing / poor use of a typedef. That makes it very unclear within the class that get_z is a method and not a variable.
    – CoryKramer
    Aug 31 at 11:27






  • 3




    ^ completely agree on that. If you add the language-lawyer tag someone might tell if this is according to the standard or not, but I dont want to see a code review that accepts this :P
    – user463035818
    Aug 31 at 11:31






  • 1




    Yes, in this example I agree completely. However, in my actual use case there are some very complex function prototypes and function pointers that I use, which make typedef-ing of a function useful (I like to think). Either way, the aim of my question is more about understanding why it will not compile, as opposed to style.
    – Globe Theatre
    Aug 31 at 11:31






  • 1




    why not typedef the returntype only? isnt that sufficient?
    – user463035818
    Aug 31 at 11:32







  • 1




    @user463035818 Another bug. A virt-specifier isn't even allowed in the syntax for a regular declaration, only in a member-declaration within a class.
    – aschepler
    Aug 31 at 11:45














up vote
15
down vote

favorite
1












C++ 11 introduced the 'override' specifier for functions and I find it useful as it makes it explicit that a virtual function is being overridden. However, I can't seem to get it work for a function that has been declared using a typedef.



I understand that 'override' is not a keyword, has it got something to do with that?



The following code illustrates my point:



#include <iostream>

typedef char ReturnsChar();

class Basic

public:
virtual char get_a();
virtual ReturnsChar get_z;
;

char Basic::get_a() return 'a';
char Basic::get_z() return 'z';

class Capitalized : public Basic

public:
// Can override explicitly if I use the normal definition
char get_a() override;

// Compiles if I use the typedef but not 'override'
ReturnsChar get_z;

// Will not compile, but would like to do this
//ReturnsChar get_z override;

;

char Capitalized::get_a() return 'A';
char Capitalized::get_z() return 'Z';

int main()

Basic foo;
Capitalized bar;

std::cout << foo.get_a() << std::endl; // a
std::cout << foo.get_z() << std::endl; // z
std::cout << bar.get_a() << std::endl; // A
std::cout << bar.get_z() << std::endl; // Z



I'm using GNU's g++ 8.2.0 and the error it gives me is




error: expected ';' at end of member declaration
ReturnsChar get_z override;
^~~~~
;
error: ‘override’ does not name a type; did you mean ‘ctermid’?
ReturnsChar get_z override;
^~~~~~~~
ctermid



EDIT: To address the comments, I understand this style is unclear. I am more interested about why this won't compile and what exactly 'override' does (especially because it is not a keyword).
As an aside, I feel like typedef-ing functions might be clear in some cases, say:



void (*foo(int x, void (*f)(int)))(int);


That's hard to read, especially if comes up often. I can just typedef that as 'UpdateAddressFunction' and then mentally think of every function of that type as something that 'updates an address'.










share|improve this question



















  • 9




    That is a really confusing / poor use of a typedef. That makes it very unclear within the class that get_z is a method and not a variable.
    – CoryKramer
    Aug 31 at 11:27






  • 3




    ^ completely agree on that. If you add the language-lawyer tag someone might tell if this is according to the standard or not, but I dont want to see a code review that accepts this :P
    – user463035818
    Aug 31 at 11:31






  • 1




    Yes, in this example I agree completely. However, in my actual use case there are some very complex function prototypes and function pointers that I use, which make typedef-ing of a function useful (I like to think). Either way, the aim of my question is more about understanding why it will not compile, as opposed to style.
    – Globe Theatre
    Aug 31 at 11:31






  • 1




    why not typedef the returntype only? isnt that sufficient?
    – user463035818
    Aug 31 at 11:32







  • 1




    @user463035818 Another bug. A virt-specifier isn't even allowed in the syntax for a regular declaration, only in a member-declaration within a class.
    – aschepler
    Aug 31 at 11:45












up vote
15
down vote

favorite
1









up vote
15
down vote

favorite
1






1





C++ 11 introduced the 'override' specifier for functions and I find it useful as it makes it explicit that a virtual function is being overridden. However, I can't seem to get it work for a function that has been declared using a typedef.



I understand that 'override' is not a keyword, has it got something to do with that?



The following code illustrates my point:



#include <iostream>

typedef char ReturnsChar();

class Basic

public:
virtual char get_a();
virtual ReturnsChar get_z;
;

char Basic::get_a() return 'a';
char Basic::get_z() return 'z';

class Capitalized : public Basic

public:
// Can override explicitly if I use the normal definition
char get_a() override;

// Compiles if I use the typedef but not 'override'
ReturnsChar get_z;

// Will not compile, but would like to do this
//ReturnsChar get_z override;

;

char Capitalized::get_a() return 'A';
char Capitalized::get_z() return 'Z';

int main()

Basic foo;
Capitalized bar;

std::cout << foo.get_a() << std::endl; // a
std::cout << foo.get_z() << std::endl; // z
std::cout << bar.get_a() << std::endl; // A
std::cout << bar.get_z() << std::endl; // Z



I'm using GNU's g++ 8.2.0 and the error it gives me is




error: expected ';' at end of member declaration
ReturnsChar get_z override;
^~~~~
;
error: ‘override’ does not name a type; did you mean ‘ctermid’?
ReturnsChar get_z override;
^~~~~~~~
ctermid



EDIT: To address the comments, I understand this style is unclear. I am more interested about why this won't compile and what exactly 'override' does (especially because it is not a keyword).
As an aside, I feel like typedef-ing functions might be clear in some cases, say:



void (*foo(int x, void (*f)(int)))(int);


That's hard to read, especially if comes up often. I can just typedef that as 'UpdateAddressFunction' and then mentally think of every function of that type as something that 'updates an address'.










share|improve this question















C++ 11 introduced the 'override' specifier for functions and I find it useful as it makes it explicit that a virtual function is being overridden. However, I can't seem to get it work for a function that has been declared using a typedef.



I understand that 'override' is not a keyword, has it got something to do with that?



The following code illustrates my point:



#include <iostream>

typedef char ReturnsChar();

class Basic

public:
virtual char get_a();
virtual ReturnsChar get_z;
;

char Basic::get_a() return 'a';
char Basic::get_z() return 'z';

class Capitalized : public Basic

public:
// Can override explicitly if I use the normal definition
char get_a() override;

// Compiles if I use the typedef but not 'override'
ReturnsChar get_z;

// Will not compile, but would like to do this
//ReturnsChar get_z override;

;

char Capitalized::get_a() return 'A';
char Capitalized::get_z() return 'Z';

int main()

Basic foo;
Capitalized bar;

std::cout << foo.get_a() << std::endl; // a
std::cout << foo.get_z() << std::endl; // z
std::cout << bar.get_a() << std::endl; // A
std::cout << bar.get_z() << std::endl; // Z



I'm using GNU's g++ 8.2.0 and the error it gives me is




error: expected ';' at end of member declaration
ReturnsChar get_z override;
^~~~~
;
error: ‘override’ does not name a type; did you mean ‘ctermid’?
ReturnsChar get_z override;
^~~~~~~~
ctermid



EDIT: To address the comments, I understand this style is unclear. I am more interested about why this won't compile and what exactly 'override' does (especially because it is not a keyword).
As an aside, I feel like typedef-ing functions might be clear in some cases, say:



void (*foo(int x, void (*f)(int)))(int);


That's hard to read, especially if comes up often. I can just typedef that as 'UpdateAddressFunction' and then mentally think of every function of that type as something that 'updates an address'.







c++ c++11 c++14 language-lawyer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 31 at 16:40

























asked Aug 31 at 11:24









Globe Theatre

23018




23018







  • 9




    That is a really confusing / poor use of a typedef. That makes it very unclear within the class that get_z is a method and not a variable.
    – CoryKramer
    Aug 31 at 11:27






  • 3




    ^ completely agree on that. If you add the language-lawyer tag someone might tell if this is according to the standard or not, but I dont want to see a code review that accepts this :P
    – user463035818
    Aug 31 at 11:31






  • 1




    Yes, in this example I agree completely. However, in my actual use case there are some very complex function prototypes and function pointers that I use, which make typedef-ing of a function useful (I like to think). Either way, the aim of my question is more about understanding why it will not compile, as opposed to style.
    – Globe Theatre
    Aug 31 at 11:31






  • 1




    why not typedef the returntype only? isnt that sufficient?
    – user463035818
    Aug 31 at 11:32







  • 1




    @user463035818 Another bug. A virt-specifier isn't even allowed in the syntax for a regular declaration, only in a member-declaration within a class.
    – aschepler
    Aug 31 at 11:45












  • 9




    That is a really confusing / poor use of a typedef. That makes it very unclear within the class that get_z is a method and not a variable.
    – CoryKramer
    Aug 31 at 11:27






  • 3




    ^ completely agree on that. If you add the language-lawyer tag someone might tell if this is according to the standard or not, but I dont want to see a code review that accepts this :P
    – user463035818
    Aug 31 at 11:31






  • 1




    Yes, in this example I agree completely. However, in my actual use case there are some very complex function prototypes and function pointers that I use, which make typedef-ing of a function useful (I like to think). Either way, the aim of my question is more about understanding why it will not compile, as opposed to style.
    – Globe Theatre
    Aug 31 at 11:31






  • 1




    why not typedef the returntype only? isnt that sufficient?
    – user463035818
    Aug 31 at 11:32







  • 1




    @user463035818 Another bug. A virt-specifier isn't even allowed in the syntax for a regular declaration, only in a member-declaration within a class.
    – aschepler
    Aug 31 at 11:45







9




9




That is a really confusing / poor use of a typedef. That makes it very unclear within the class that get_z is a method and not a variable.
– CoryKramer
Aug 31 at 11:27




That is a really confusing / poor use of a typedef. That makes it very unclear within the class that get_z is a method and not a variable.
– CoryKramer
Aug 31 at 11:27




3




3




^ completely agree on that. If you add the language-lawyer tag someone might tell if this is according to the standard or not, but I dont want to see a code review that accepts this :P
– user463035818
Aug 31 at 11:31




^ completely agree on that. If you add the language-lawyer tag someone might tell if this is according to the standard or not, but I dont want to see a code review that accepts this :P
– user463035818
Aug 31 at 11:31




1




1




Yes, in this example I agree completely. However, in my actual use case there are some very complex function prototypes and function pointers that I use, which make typedef-ing of a function useful (I like to think). Either way, the aim of my question is more about understanding why it will not compile, as opposed to style.
– Globe Theatre
Aug 31 at 11:31




Yes, in this example I agree completely. However, in my actual use case there are some very complex function prototypes and function pointers that I use, which make typedef-ing of a function useful (I like to think). Either way, the aim of my question is more about understanding why it will not compile, as opposed to style.
– Globe Theatre
Aug 31 at 11:31




1




1




why not typedef the returntype only? isnt that sufficient?
– user463035818
Aug 31 at 11:32





why not typedef the returntype only? isnt that sufficient?
– user463035818
Aug 31 at 11:32





1




1




@user463035818 Another bug. A virt-specifier isn't even allowed in the syntax for a regular declaration, only in a member-declaration within a class.
– aschepler
Aug 31 at 11:45




@user463035818 Another bug. A virt-specifier isn't even allowed in the syntax for a regular declaration, only in a member-declaration within a class.
– aschepler
Aug 31 at 11:45












1 Answer
1






active

oldest

votes

















up vote
23
down vote



accepted











I understand that 'override' is not a keyword, has it got something to do with that?




It does: override is only recognised in a few specific contexts and is available as a name for ordinary use otherwise. However, I believe this is a compiler bug, and this is one context where the compiler should recognise it in its special meaning.



The relevant grammatical production for this is




[class.mem]



member-declarator:

  declarator virt-specifier-seqopt pure-specifieropt




This does not require that a virt-specifier-seq only appear in a declaration containing parameters. The only similar requirement is stated below:




[class.mem]p8:



A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).




In your case, the declaration is one of a virtual member function. I believe override should be accepted here.






share|improve this answer




















  • The one catch is [lex.name]/2 "Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier." I don't see a way that code could be ambiguous, but I'm not 100% certain.
    – aschepler
    Aug 31 at 11:39










  • Thanks, this is very clear. I'm quite pleased that I've discovered an actual compiler bug, that's one to tick off the bucket list!
    – Globe Theatre
    Aug 31 at 11:45










  • @aschepler Good point. I think there are some similar cases with ambiguities. I think struct A struct B ; struct B override; ; might be one, which because of what you quoted declares a non-static data member named override.
    – hvd
    Aug 31 at 11:45











  • Did you already file some bug reports?
    – Rakete1111
    Aug 31 at 15:41






  • 2




    @hvd Done: gcc.gnu.org/bugzilla/show_bug.cgi?id=87174
    – Rakete1111
    Aug 31 at 18:07










Your Answer





StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52114447%2fusing-override-for-a-function-that-has-been-declared-using-typedef%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
23
down vote



accepted











I understand that 'override' is not a keyword, has it got something to do with that?




It does: override is only recognised in a few specific contexts and is available as a name for ordinary use otherwise. However, I believe this is a compiler bug, and this is one context where the compiler should recognise it in its special meaning.



The relevant grammatical production for this is




[class.mem]



member-declarator:

  declarator virt-specifier-seqopt pure-specifieropt




This does not require that a virt-specifier-seq only appear in a declaration containing parameters. The only similar requirement is stated below:




[class.mem]p8:



A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).




In your case, the declaration is one of a virtual member function. I believe override should be accepted here.






share|improve this answer




















  • The one catch is [lex.name]/2 "Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier." I don't see a way that code could be ambiguous, but I'm not 100% certain.
    – aschepler
    Aug 31 at 11:39










  • Thanks, this is very clear. I'm quite pleased that I've discovered an actual compiler bug, that's one to tick off the bucket list!
    – Globe Theatre
    Aug 31 at 11:45










  • @aschepler Good point. I think there are some similar cases with ambiguities. I think struct A struct B ; struct B override; ; might be one, which because of what you quoted declares a non-static data member named override.
    – hvd
    Aug 31 at 11:45











  • Did you already file some bug reports?
    – Rakete1111
    Aug 31 at 15:41






  • 2




    @hvd Done: gcc.gnu.org/bugzilla/show_bug.cgi?id=87174
    – Rakete1111
    Aug 31 at 18:07














up vote
23
down vote



accepted











I understand that 'override' is not a keyword, has it got something to do with that?




It does: override is only recognised in a few specific contexts and is available as a name for ordinary use otherwise. However, I believe this is a compiler bug, and this is one context where the compiler should recognise it in its special meaning.



The relevant grammatical production for this is




[class.mem]



member-declarator:

  declarator virt-specifier-seqopt pure-specifieropt




This does not require that a virt-specifier-seq only appear in a declaration containing parameters. The only similar requirement is stated below:




[class.mem]p8:



A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).




In your case, the declaration is one of a virtual member function. I believe override should be accepted here.






share|improve this answer




















  • The one catch is [lex.name]/2 "Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier." I don't see a way that code could be ambiguous, but I'm not 100% certain.
    – aschepler
    Aug 31 at 11:39










  • Thanks, this is very clear. I'm quite pleased that I've discovered an actual compiler bug, that's one to tick off the bucket list!
    – Globe Theatre
    Aug 31 at 11:45










  • @aschepler Good point. I think there are some similar cases with ambiguities. I think struct A struct B ; struct B override; ; might be one, which because of what you quoted declares a non-static data member named override.
    – hvd
    Aug 31 at 11:45











  • Did you already file some bug reports?
    – Rakete1111
    Aug 31 at 15:41






  • 2




    @hvd Done: gcc.gnu.org/bugzilla/show_bug.cgi?id=87174
    – Rakete1111
    Aug 31 at 18:07












up vote
23
down vote



accepted







up vote
23
down vote



accepted







I understand that 'override' is not a keyword, has it got something to do with that?




It does: override is only recognised in a few specific contexts and is available as a name for ordinary use otherwise. However, I believe this is a compiler bug, and this is one context where the compiler should recognise it in its special meaning.



The relevant grammatical production for this is




[class.mem]



member-declarator:

  declarator virt-specifier-seqopt pure-specifieropt




This does not require that a virt-specifier-seq only appear in a declaration containing parameters. The only similar requirement is stated below:




[class.mem]p8:



A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).




In your case, the declaration is one of a virtual member function. I believe override should be accepted here.






share|improve this answer













I understand that 'override' is not a keyword, has it got something to do with that?




It does: override is only recognised in a few specific contexts and is available as a name for ordinary use otherwise. However, I believe this is a compiler bug, and this is one context where the compiler should recognise it in its special meaning.



The relevant grammatical production for this is




[class.mem]



member-declarator:

  declarator virt-specifier-seqopt pure-specifieropt




This does not require that a virt-specifier-seq only appear in a declaration containing parameters. The only similar requirement is stated below:




[class.mem]p8:



A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).




In your case, the declaration is one of a virtual member function. I believe override should be accepted here.







share|improve this answer












share|improve this answer



share|improve this answer










answered Aug 31 at 11:36









hvd

113k11194273




113k11194273











  • The one catch is [lex.name]/2 "Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier." I don't see a way that code could be ambiguous, but I'm not 100% certain.
    – aschepler
    Aug 31 at 11:39










  • Thanks, this is very clear. I'm quite pleased that I've discovered an actual compiler bug, that's one to tick off the bucket list!
    – Globe Theatre
    Aug 31 at 11:45










  • @aschepler Good point. I think there are some similar cases with ambiguities. I think struct A struct B ; struct B override; ; might be one, which because of what you quoted declares a non-static data member named override.
    – hvd
    Aug 31 at 11:45











  • Did you already file some bug reports?
    – Rakete1111
    Aug 31 at 15:41






  • 2




    @hvd Done: gcc.gnu.org/bugzilla/show_bug.cgi?id=87174
    – Rakete1111
    Aug 31 at 18:07
















  • The one catch is [lex.name]/2 "Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier." I don't see a way that code could be ambiguous, but I'm not 100% certain.
    – aschepler
    Aug 31 at 11:39










  • Thanks, this is very clear. I'm quite pleased that I've discovered an actual compiler bug, that's one to tick off the bucket list!
    – Globe Theatre
    Aug 31 at 11:45










  • @aschepler Good point. I think there are some similar cases with ambiguities. I think struct A struct B ; struct B override; ; might be one, which because of what you quoted declares a non-static data member named override.
    – hvd
    Aug 31 at 11:45











  • Did you already file some bug reports?
    – Rakete1111
    Aug 31 at 15:41






  • 2




    @hvd Done: gcc.gnu.org/bugzilla/show_bug.cgi?id=87174
    – Rakete1111
    Aug 31 at 18:07















The one catch is [lex.name]/2 "Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier." I don't see a way that code could be ambiguous, but I'm not 100% certain.
– aschepler
Aug 31 at 11:39




The one catch is [lex.name]/2 "Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier." I don't see a way that code could be ambiguous, but I'm not 100% certain.
– aschepler
Aug 31 at 11:39












Thanks, this is very clear. I'm quite pleased that I've discovered an actual compiler bug, that's one to tick off the bucket list!
– Globe Theatre
Aug 31 at 11:45




Thanks, this is very clear. I'm quite pleased that I've discovered an actual compiler bug, that's one to tick off the bucket list!
– Globe Theatre
Aug 31 at 11:45












@aschepler Good point. I think there are some similar cases with ambiguities. I think struct A struct B ; struct B override; ; might be one, which because of what you quoted declares a non-static data member named override.
– hvd
Aug 31 at 11:45





@aschepler Good point. I think there are some similar cases with ambiguities. I think struct A struct B ; struct B override; ; might be one, which because of what you quoted declares a non-static data member named override.
– hvd
Aug 31 at 11:45













Did you already file some bug reports?
– Rakete1111
Aug 31 at 15:41




Did you already file some bug reports?
– Rakete1111
Aug 31 at 15:41




2




2




@hvd Done: gcc.gnu.org/bugzilla/show_bug.cgi?id=87174
– Rakete1111
Aug 31 at 18:07




@hvd Done: gcc.gnu.org/bugzilla/show_bug.cgi?id=87174
– Rakete1111
Aug 31 at 18:07

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52114447%2fusing-override-for-a-function-that-has-been-declared-using-typedef%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Christian Cage

How to properly install USB display driver for Fresco Logic FL2000DX on Ubuntu?