Re: Passing Structs to function like in C

2016-08-14 Thread Cauterite via Digitalmars-d-learn

On Sunday, 14 August 2016 at 16:21:58 UTC, D.Rex wrote:

so '();' works the same as 'foo.bar();'?


with pointers, D automatically rewrites expressions like this:
f.fooMethod()
to this:
(*f).fooMethod()
which is why you're able to index an object-pointer-pointer 
(Foo*) the same way as an object-pointer (Foo).


Most built-in D types have value semantics, so it's 
understandable that you wouldn't expect classes to be reference 
types.


Associative arrays are also reference types, FYI.

Structs on the other hand are value types; if you're new to the 
language make sure you familiarise yourself with the differences 
between structs and classes.


Re: Passing Structs to function like in C

2016-08-14 Thread D.Rex via Digitalmars-d-learn

On Sunday, 14 August 2016 at 14:59:17 UTC, Adam D. Ruppe wrote:

On Sunday, 14 August 2016 at 14:54:27 UTC, D.Rex wrote:
Speaking of classes, and this may have been answered 
elsewhere, but I am yet to find said answer, or am just 
missing something right in front of my face...but how does one 
go about accessing a method from a class if said class is 
passed to a function as a pointer?


It just works with the regular dot.

But don't pass classes as pointers in D except in very rare 
circumstances. They are already pointers under the hood 
automatically.


So you can access a method from a class pointer the same way you 
would access a method from a class normally?


so '();' works the same as 'foo.bar();'?

ah that makes sense, classes being pointers behind the scenes, 
Most of my programming experience is in Java, so the usage of 
pointers is a rather new concept for me.


Thank you kindly for your answer, much appreciated!! :-)


Re: Passing Structs to function like in C

2016-08-14 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 14 August 2016 at 14:54:27 UTC, D.Rex wrote:
Speaking of classes, and this may have been answered elsewhere, 
but I am yet to find said answer, or am just missing something 
right in front of my face...but how does one go about accessing 
a method from a class if said class is passed to a function as 
a pointer?


It just works with the regular dot.

But don't pass classes as pointers in D except in very rare 
circumstances. They are already pointers under the hood 
automatically.


Re: Passing Structs to function like in C

2016-08-14 Thread D.Rex via Digitalmars-d-learn

On Saturday, 13 August 2016 at 18:37:54 UTC, Cauterite wrote:

On Saturday, 13 August 2016 at 15:47:51 UTC, D.Rex wrote:

/* memory.d file */
module memory;
import include.linux.sched;/* contains task_struct 
definition */


void free_page_tables(task_struct* tsk) {
/* do something with  */
}

And to use the method from somewhere else
/* use method.d */

module usemethod;
import include.linux.sched;
import mm.memory;

void some method() {
free_page_tables(*pointer to task_struct*);
}

I hope my explanation is not rambling nonsense.

Cheers.


Yes, you're right. Passing structure pointers to functions is 
an extremely common practice in C, because there aren't really 
any other compelling options. In D we have things like methods, 
classes, 'const ref' params, return-type inference, etc., so 
there's usually a better way to achieve the same result.


Cheers!!

Speaking of classes, and this may have been answered elsewhere, 
but I am yet to find said answer, or am just missing something 
right in front of my face...but how does one go about accessing a 
method from a class if said class is passed to a function as a 
pointer?  By that I mean something like


class Foo {
void fooMethod() {
}
}

void bar(Foo *f) {
/* access fooMethod from  */
}

Thanks for all your help, I really appreciate it!!


Re: Passing Structs to function like in C

2016-08-14 Thread D.Rex via Digitalmars-d-learn

On Saturday, 13 August 2016 at 18:37:54 UTC, Cauterite wrote:

On Saturday, 13 August 2016 at 15:47:51 UTC, D.Rex wrote:

/* memory.d file */
module memory;
import include.linux.sched;/* contains task_struct 
definition */


void free_page_tables(task_struct* tsk) {
/* do something with  */
}

And to use the method from somewhere else
/* use method.d */

module usemethod;
import include.linux.sched;
import mm.memory;

void some method() {
free_page_tables(*pointer to task_struct*);
}

I hope my explanation is not rambling nonsense.

Cheers.


Yes, you're right. Passing structure pointers to functions is 
an extremely common practice in C, because there aren't really 
any other compelling options. In D we have things like methods, 
classes, 'const ref' params, return-type inference, etc., so 
there's usually a better way to achieve the same result.


Cheers!!

Speaking of classes, and this may have been answered elsewhere, 
but I am yet to find said answer, or am just missing something 
right in front of my face...but how does one go about accessing a 
method from a class if said class is passed to a function as a 
pointer?  By that I mean something like


class Foo {
void fooMethod() {

}

void bar(Foo *f) {

}


Re: Passing Structs to function like in C

2016-08-13 Thread ag0aep6g via Digitalmars-d-learn

On 08/13/2016 09:23 PM, Engine Machine wrote:

Then it should error if it doesn't accept ';'. If it accepts it then it
is legal.


It is legal, yes. It's also pointless and misleading. It should be 
pointed out for the benefit of the author, as they may have a 
misconception about D syntax. It should also be pointed out so that 
others don't form such misconceptions.


[...]

It is not a mistake... only in your mind.


In my experience, an empty declaration or statement is usually a 
mistake. And it's usually done by people coming from C. If it's not a 
mistake, it's a pretty weird style choice.


A similar thing is `return(foo);`. I'd point that out, too, because like 
the extra semicolon, it looks like it might be necessary syntax, but 
it's really just extra punctuation without purpose.


Of course, everyone is free to write their code however they want. But 
if you post here, it can't be surprising when you get feedback on it. 
Especially when it's an answer to someone else, which means it's more 
important to write good code, because you're influencing someone who's 
learning.



If it was a mistake D wouldn't allow it.


D deliberately allows many mistakes, and they can be much more serious 
than the little style mishap at hand.


[...]

There is no point in a lot of things, but pretending that life depends
on such trivial things is a much worse mistake, IMO.


I originally wrote one little line on this. I don't think anyone here is 
"pretending that life depends on" it.


Re: Passing Structs to function like in C

2016-08-13 Thread Engine Machine via Digitalmars-d-learn

On Friday, 12 August 2016 at 17:53:12 UTC, ag0aep6g wrote:

On 08/12/2016 07:33 PM, Cauterite wrote:

Why would I not terminate a declaration with a semi-colon?
Why should a declaration not end in a semi-colon just because 
the last

token is a brace?
Why should I not tell the lexer precisely where my declaration 
ends
instead of relying on whatever other tokens floating around it 
not

interfering?


The semicolon is just noise. You're not helping the lexer at 
all. It goes by the braces, and doesn't see the semicolon as 
belonging to the function declaration. The semicolon creates 
another, empty declaration.


Then it should error if it doesn't accept ';'. If it accepts it 
then it is legal. Your post is noise since it also is relatively 
meaningless and just takes up space. Why is it no ok for him to 
add a noisy ';' but it is ok for you to add noise to noise by 
adding a noisy post?



This is accepted as well, and means the same:


;;;
void main() {}
;;;


Why must every thread in this forum contain more posts 
regarding some

irrelevant tangent than posts responding to the original topic?


This is a common mistake - more for structs, though, because of 
C syntax. So I point it out so that you can learn that there's 
no point to it in D, and so that others don't get the 
impression that it's the proper syntax.



It is not a mistake... only in your mind. If it was a mistake D 
wouldn't allow it. Somewhere you picked up the mistake that 
adding a semicolon to the end of a struct is a mistake. Maybe you 
should unlearn that mistake?


There is no point in a lot of things, but pretending that life 
depends on such trivial things is a much worse mistake, IMO.





Re: Passing Structs to function like in C

2016-08-13 Thread Engine Machine via Digitalmars-d-learn

On Friday, 12 August 2016 at 18:23:55 UTC, Cauterite wrote:

Thanks colon-nazis, I'll take that into consideration ¬_¬


Be careful! They will cauterize your testicles and rape your 
children! Those semi-clone, I mean semi-colon-nazis are the worse 
kind!  It's a life and death matter! After all, `proper`(by 
section 8.043 of the penile nazile book of the dead) use of ';' 
is more important than your testicles anyways, right?








Re: Passing Structs to function like in C

2016-08-13 Thread Cauterite via Digitalmars-d-learn

On Saturday, 13 August 2016 at 15:47:51 UTC, D.Rex wrote:

/* memory.d file */
module memory;
import include.linux.sched;/* contains task_struct 
definition */


void free_page_tables(task_struct* tsk) {
/* do something with  */
}

And to use the method from somewhere else
/* use method.d */

module usemethod;
import include.linux.sched;
import mm.memory;

void some method() {
free_page_tables(*pointer to task_struct*);
}

I hope my explanation is not rambling nonsense.

Cheers.


Yes, you're right. Passing structure pointers to functions is an 
extremely common practice in C, because there aren't really any 
other compelling options. In D we have things like methods, 
classes, 'const ref' params, return-type inference, etc., so 
there's usually a better way to achieve the same result.


Re: Passing Structs to function like in C

2016-08-12 Thread cy via Digitalmars-d-learn

On Friday, 12 August 2016 at 15:21:22 UTC, D.Rex wrote:
I was wondering how this is achieved in D, or if D has an 
alternative implementation of this.


It isn't, because C interfaces that require you to pass in 
structures are inherently bad design, and usually both unstable 
and extremely C specific. Nobody wants to bother with that, and 
get stuck maintaining it to boot. You have to re-define the 
struct in D's language in order to comprehend it, but then you 
look in libuv and you see things like:


struct uv_shutdown_s {
  UV_REQ_FIELDS
  uv_stream_t* handle;
  uv_shutdown_cb cb;
  UV_SHUTDOWN_PRIVATE_FIELDS
};

and you let out a slow, agonized groan of disgust, because now 
you have to go searching through the CPP parser output manually 
to determine the nature of the struct. Once you've done that, 
your code is unstable and likely to stop working with even minor 
version changes, because the C programmers used those #define 
statements on the assumption that what substitutes in there won't 
always remain the same. And since C doesn't check the size of a 
structure, you usually get no error when they add another byte in 
the middle, only silent failures and breakage.


But... assuming you're forced to do this, you'd run the header 
file through cpp with all the relevant flags. There is no parser 
for C that works in the general case (and C programmers just LOVE 
using all the horrible edge cases), but you can just manually go 
through and look at the structures you want to use. For instance:


struct uv_shutdown_s {
  void* data; uv_req_type type; void* active_queue[2]; void* 
reserved[4];

  uv_stream_t* handle;
  uv_shutdown_cb cb;

};

cpp doesn't fill in typedefs, so you have to manually go and look 
at what those are (and hope that they don't change depending on 
compilation parameters). Oh, and I should mention cpp erases all 
newlines, so any substitution is all going to be crammed on a 
single line. But once you see that, then you make a uv.d file 
containing:


...

alias ShutdownCallback = void function(shutdown*, int);

struct Shutdown {
  void* data;
  Req type;
  void*[2] active_queue;
  void*[4] reserved;
  Stream* handle;
  ShutdownCallback cb;
}

as well as the same thing done for "req" (uv_req_t) and "stream" 
(uv_stream_t). Then you can just...


extern (C) int uv_shutdown(Shutdown*, Stream*, ShutdownCallback);
extern (C) void* malloc(size_t);
void foo(Stream* something, int delegate() handle) {
  Shutdown* req = cast(Shutdown*)malloc(Shutdown.sizeof);
  req.data = handle; // ?
  uv_shutdown(req, something, unpack_delegate);
}


...and it'll work, until they change something, or you try to 
switch to a 64 bit machine, or something.


...and if instead, libuv used an opaque structure for Shutdown 
and Stream, and functions to access its data, you could do this:


struct Shutdown;
struct Stream;
extern (C) int uv_shutdown(Shutdown*, Stream*, ShutdownCallback);
extern (C) Shutdown* uv_new_shutdown();
void foo(Stream* something, int delegate() handle) {
  Shutdown* req = uv_new_shutdown();
  req.data = handle;
  uv_shutdown(req,stream,unpack_delegate);
}

Much simpler, no? Plus it's stable even when they change the 
structure of their implementation.


When I have to write a C library, I almost always write a C 
interface that doesn't suck, in order to do the things I want 
with that library. Then at least when they change their internal 
structure, my C can recompile, and present a stable and simple 
ABI to the D side of things.


This is actually a problem for every language that's not C, not 
just D. Passing structs as arguments to your interface just 
always makes things harder for language supporters.


Re: Passing Structs to function like in C

2016-08-12 Thread Cauterite via Digitalmars-d-learn

Thanks colon-nazis, I'll take that into consideration ¬_¬


Re: Passing Structs to function like in C

2016-08-12 Thread ag0aep6g via Digitalmars-d-learn

On 08/12/2016 07:33 PM, Cauterite wrote:

Why would I not terminate a declaration with a semi-colon?
Why should a declaration not end in a semi-colon just because the last
token is a brace?
Why should I not tell the lexer precisely where my declaration ends
instead of relying on whatever other tokens floating around it not
interfering?


The semicolon is just noise. You're not helping the lexer at all. It 
goes by the braces, and doesn't see the semicolon as belonging to the 
function declaration. The semicolon creates another, empty declaration.


This is accepted as well, and means the same:


;;;
void main() {}
;;;



Why must every thread in this forum contain more posts regarding some
irrelevant tangent than posts responding to the original topic?


This is a common mistake - more for structs, though, because of C 
syntax. So I point it out so that you can learn that there's no point to 
it in D, and so that others don't get the impression that it's the 
proper syntax.


Re: Passing Structs to function like in C

2016-08-12 Thread WebFreak001 via Digitalmars-d-learn

On Friday, 12 August 2016 at 17:33:34 UTC, Cauterite wrote:

On Friday, 12 August 2016 at 16:50:43 UTC, ag0aep6g wrote:

On 08/12/2016 05:23 PM, Cauterite wrote:
No semicolon there, please.


Why would I not terminate a declaration with a semi-colon?
Why should a declaration not end in a semi-colon just because 
the last token is a brace?
Why should I not tell the lexer precisely where my declaration 
ends instead of relying on whatever other tokens floating 
around it not interfering?
Why must every thread in this forum contain more posts 
regarding some irrelevant tangent than posts responding to the 
original topic?


That would be like putting a semicolon after a while or if block 
or after defining a delegate inside an argument list.


I think it's a bug that dmd doesn't show a warning for 
unnecessary semicolons outside of function blocks, because inside 
of them it also shows a warning.


Also it's not D-style to put a semicolon there and it's also 
never specified in the grammar spec. It's just treated as 
separate empty statement.


Re: Passing Structs to function like in C

2016-08-12 Thread Cauterite via Digitalmars-d-learn

On Friday, 12 August 2016 at 16:50:43 UTC, ag0aep6g wrote:

On 08/12/2016 05:23 PM, Cauterite wrote:
No semicolon there, please.


Why would I not terminate a declaration with a semi-colon?
Why should a declaration not end in a semi-colon just because the 
last token is a brace?
Why should I not tell the lexer precisely where my declaration 
ends instead of relying on whatever other tokens floating around 
it not interfering?
Why must every thread in this forum contain more posts regarding 
some irrelevant tangent than posts responding to the original 
topic?


Re: Passing Structs to function like in C

2016-08-12 Thread ag0aep6g via Digitalmars-d-learn

On 08/12/2016 05:23 PM, Cauterite wrote:

void main() {

[...]

};


No semicolon there, please.


Re: Passing Structs to function like in C

2016-08-12 Thread Cauterite via Digitalmars-d-learn

On Friday, 12 August 2016 at 15:21:22 UTC, D.Rex wrote:

extern unsigned long free_page_tables(struct task_struct * tsk);


extern(C) ulong free_page_tables(task_struct* tsk);

void main() {
task_struct tsk =  …… ;
free_page_tables();
};

That should be what you're after?


Passing Structs to function like in C

2016-08-12 Thread D.Rex via Digitalmars-d-learn

Hi,

This has probably been asked many times before, but after search 
for hours and hours I can't find an answer.  I have seen in C an 
extern function taking in a struct as one of its parameters, like 
so:


extern unsigned long free_page_tables(struct task_struct * tsk);

I was wondering how this is achieved in D, or if D has an 
alternative implementation of this.


Cheers.