Path: csiph.com!usenet.pasdenom.info!news.etla.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed1a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'python,': 0.02; 'subject:: [': 0.04; 'subject:Python': 0.06; 'padding': 0.07; 'puts': 0.07; '#include': 0.09; '[],': 0.09; 'bytes,': 0.09; 'definition,': 0.09; 'inherited': 0.09; 'main()': 0.09; 'skip:% 20': 0.09; 'subject:into': 0.09; 'sucks': 0.09; 'sure,': 0.09; 'cc:addr :python-list': 0.11; '240': 0.16; 'block.': 0.16; 'element.': 0.16; 'foo,': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'hmm.': 0.16; 'none),': 0.16; 'sizeof(int)': 0.16; 'sizeof.': 0.16; 'structs': 0.16; 'subject:variable': 0.16; 'size,': 0.16; 'wrote:': 0.18; 'obviously': 0.18; 'starts': 0.20; 'subject:] ': 0.20; 'memory': 0.22; 'rules': 0.22; 'cc:addr:python.org': 0.22; 'bytes': 0.24; 'convenient': 0.24; 'instance,': 0.24; 'pointer': 0.24; 'skip:% 10': 0.24; 'mon,': 0.24; 'versions': 0.24; 'cc:2**0': 0.24; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'am,': 0.29; 'array': 0.29; 'room': 0.29; '(like': 0.30; 'returned': 0.30; 'specified': 0.30; 'message- id:@mail.gmail.com': 0.30; '(which': 0.31; 'included': 0.31; '120': 0.31; 'aligned': 0.31; 'block,': 0.31; 'obliged': 0.31; 'overhead': 0.31; 'struct': 0.31; 'class': 0.32; 'beginning': 0.33; 'cases': 0.33; 'table': 0.34; 'case,': 0.35; 'definition': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'subject:?': 0.36; 'virtual': 0.37; 'needed': 0.38; 'previous': 0.38; 'that,': 0.38; 'structure': 0.39; 'skip:p 20': 0.39; 'dave': 0.60; 'subject:Can': 0.60; 'new': 0.61; 'skip:* 10': 0.61; 'first': 0.61; 'such': 0.63; 'choose': 0.64; 'effectively': 0.66; 'between': 0.67; 'mar': 0.68; 'acts': 0.74; 'eight': 0.74; 'laid': 0.84; 'presumably': 0.84; 'angel': 0.91; 'to:none': 0.92 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=Hs/jvz8q3etq0yBP8yLzBgIxFdOoB/WC3948tWmAcKo=; b=sB5s9GHuW8wUEBnxqqs2/3GbqlLpBoEcTOqI3XvDffD5ZyZpuVHFtBrQeZhuNOvKOa ao08dq2Lz4gyd8L6GhV0fBtzU7EwEpJBaFdEd0oY4GjFPSE8VzWLxHLsuadiT77Etz5K 0KXC10F+Nd46kNx5OUJxT/vLGMn09nhXyBD+/99WDERmYs9+R6eWYo0Ow87X+DB0ftxZ kRVoNdNVrNDVu+uNx/G3td8QPNjAWmrsp0CnnxRKQ/BSRPhrZGlbEZEOXrCJTOsmYdRN MbgIjt6J/T1LnIpBoX+EexGfprYvBtMpvvS+fE3fNiK4glPnvhCz9s5yI19e8Mmvdwgw pC+w== MIME-Version: 1.0 X-Received: by 10.66.164.165 with SMTP id yr5mr14002147pab.63.1393768647329; Sun, 02 Mar 2014 05:57:27 -0800 (PST) In-Reply-To: References: <27ac2248-0ca3-4ba6-9d25-eaad324bc5e9@googlegroups.com> <87sird7wuw.fsf@handshake.de> <8454E8CB-E6E3-452F-8E54-9A77BFF34EC2@gmail.com> <1m3gg9lbf2ln5m2kbki954t17mqni3b20k@4ax.com> <53095145$0$29985$c3e8da3$5496439d@news.astraweb.com> <877g8mcg1m.fsf@elektro.pacujo.net> <87ob1yay9m.fsf@elektro.pacujo.net> <08aa32de-cd51-4888-bd60-2c2b53d86ecc@googlegroups.com> Date: Mon, 3 Mar 2014 00:57:27 +1100 Subject: Re: [OT] Can global variable be passed into Python function? From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 78 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1393770033 news.xs4all.nl 2916 [2001:888:2000:d::a6]:41734 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:67442 On Mon, Mar 3, 2014 at 12:22 AM, Dave Angel wrote: > Sure, for some definition of "usable". Overhead such as block > size, freelist pointer etc., are obviously outside of the > returned block. But the array size that's specified in a call to > new [], and the vptr, are definitely inside the malloc'ed block, > and may be before the struct data. Hmm. Last I was working with it, the array size to new[] was outside the block, just as the block size to malloc(). The vptr is part of any struct/class with virtual functions, and effectively acts as a hidden class member, so you get one of those inside the block, and it's included in sizeof. //Allocated Space: The Final Frontier! #include //cout sucks :) class Foo { int x; int y; int z; }; class Bar { int x; int y; int z; virtual int get_x() {return x;} }; int main() { printf("sizeof(int) = %u\n",sizeof(int)); printf("sizeof(int*) = %u\n",sizeof(int*)); printf("sizeof(Foo) = %u\n",sizeof(Foo)); printf("sizeof(Bar) = %u\n",sizeof(Bar)); Foo *foo = new Foo[10]; printf("foo = %p/%p = %u\n",foo,foo+10,(char *)(foo+10)-(char *)foo); Bar *bar = new Bar[10]; printf("bar = %p/%p = %u\n",bar,bar+10,(char *)(bar+10)-(char *)bar); return 0; } rosuav@sikorsky:~$ g++ frontier.cpp && ./a.out sizeof(int) = 4 sizeof(int*) = 8 sizeof(Foo) = 12 sizeof(Bar) = 24 foo = 0xf38010/0xf38088 = 120 bar = 0xf38090/0xf38180 = 240 The rules of structs are that they be contiguous, that they be laid out sequentially, and that any padding needed between structures is at the end of the previous one (which is why three of 4 bytes makes 12 bytes, but three of 4 bytes plus 8 bytes makes 24 - the eight-byte pointer has to be aligned on a multiple of eight bytes, so having a 20-byte structure that starts with an 8-byte pointer is a no-no). The allocated block of memory is, by definition, the same as the pointer to its first element. As it happens, the pointer bar is not synonymous with &bar->x, &bar->y, or &bar->z, which means the vptr is at the beginning of bar, which makes sense; but the compiler's not obliged to do that, and in some cases may choose not to - for instance, if bar (with a virtual function) inherited from foo (with none), it might be convenient to allow a pointer-cast to not change the value of the pointer. (g++ 4.7.2 still puts the vptr at the beginning of bar in that case, but other compilers or other versions may differ.) Array size is outside the block, presumably before it, as &foo[0] is by definition identical to foo, and there's no room inside the structure for any spare data. Virtual function table is inside the block because it's a hidden member of the object (like __class__ in Python, only better hidden). ChrisA