精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

直擊VS2010中的std::tr1 bind庫BUG

開發 后端
今天我們將看到的是Visual Studio 2010中一個BUG被捉住的過程。也就是std::tr1 bind庫BUG。

前兩天發現了VC2010 tr1庫中bind實現的一個bug,當時只是作了記錄,沒有詳細分析.但作為一個QA,不找出問題所在實在不算稱職,于是就有了這篇捉蟲記.

閑言少敘,書歸正傳,tr1庫就不多作介紹了,有興趣的同學可以去 wikipedia上看.bind,顧名思義,就是把參數與函數綁定,以利于我們進行函數式編程,是從boost的bind庫引入的,對bind不是很了解的可以看陳碩同學的這篇

以boost::function和boost:bind取代虛函數

假定筆者是 VC2010的QA,在做bind的功能測試,開始用gtest寫test case, (筆者一般用gtest作為C++測試框架,就寫到文章中了,但ms肯定不會用啦.筆者不在ms,請勿對號入座)

先寫幾個簡單的函數供測試之用. 

  1. int Add(int left, int right)  
  2. {  
  3. return left + right;  
  4. }  
  5. int Sub(int left, int right)  
  6. {  
  7. return left - right;  
  8. }  
  9. int Mul(int left, int right)  
  10. {  
  11. return left * right;  

再寫測試用例.先是幾個簡單的

1 把值綁定到函數指針

  1. TEST(Bind, FundPtr_Values)   
  2. {   
  3. auto f0 = std::tr1::bind(Sub, 5, 3);   
  4. ASSERT_EQ(2, f0());   

2 把值綁定到仿函數

  1. TEST(Bind, Functor_Values)   
  2. {   
  3. auto f0 = std::tr1::bind(std::minus<int>(), 6, 4);   
  4. ASSERT_EQ(2, f0());   

3 把占位符綁定到函數指針

  1. TEST(Bind, FuncPtr_Placeholder)  
  2. {  
  3. auto f0 = std::tr1::bind(Sub, std::tr1::placeholders::_1, 8);  
  4. ASSERT_EQ(12, f0(20));  

4 將占位符綁定到仿函數

  1. TEST(Bind, Functor_Placeholder)  
  2. {  
  3. auto f0 = std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_2, std::placeholders::_1);  
  4. ASSERT_EQ(12, f0(8, 20));  

運行測試

  1. testing::InitGoogleTest(&argc, argv);  
  2. int ret = RUN_ALL_TESTS(); 

一切OK.

來個復雜的,將bind返回結果再bind到函數,用于進行高階函數演算.

組合函數指針

  1. TEST(Bind, SquareDiff_FuncPtr)  
  2. {  
  3. auto f0 = std::tr1::bind(Mul,   
  4. std::tr1::bind(Add, std::tr1::placeholders::_1, std::tr1::placeholders::_2),  
  5. std::tr1::bind(Sub, std::tr1::placeholders::_1, std::tr1::placeholders::_2));  
  6. ASSERT_EQ(16, f0(5, 3));  

運行,一切OK,

再來一個仿函數版本

組合仿函數

  1. TEST(Bind, Squarediff_Functorptr)  
  2. {  
  3. auto f0 = std::tr1::bind(std::multiplies<int>(),  
  4. std::tr1::bind(std::plus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2),  
  5. std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2));  
  6. ASSERT_EQ(16, f0(5, 3));  

編譯 , wow,這是啥啊

Error    1    error C2664: 'int std::multiplies<_Ty>::operator ()(const _Ty &,const _Ty &) const' : cannot convert parameter 1 from 'std::tr1::_Bind_fty<_Fty,_Ret,_BindN>' to 'const int &'    c:\program files\microsoft visual studio 10.0\vc\include\xxcallobj    13    1    boostDemo 

發現問題了, 偶兩眼開始放光.

現在就開bug么,不,太早了,總得指明問題在哪兒吧.是編譯器還是tr1庫實現的問題?怎么辦?拿另一個庫boost試試,正常

通過就是tr1的問題了

  1. TEST(Bind, SquareDiff_BoostFunctor)  
  2. {  
  3. auto f0 = boost::bind(std::multiplies<int>(),  
  4. boost::bind(std::plus<int>(), _1, _2),  
  5. boost::bind(std::minus<int>(),_1, _2));  
  6. ASSERT_EQ(16, f0(5, 3));  

編譯運行,一切正常.

現在可以肯定是tr1庫的問題么?還不能.也許對仿函數綁定是boost的擴展而tr1準標準并不支持呢?

打開標準,看bind參數的說明 template<class F, class T1, class T2, ...., class TN>

unspecified bind(F f, T1 t1, T2 t2, ..., TN tN);

1 Requires: F and Ti shall be CopyConstructible. INVOKE (f, w1, w2, ..., wN) ([3.3]) shall be a valid expression

for some values w1, w2, ..., wN.

2 Returns: A forwarding call wrapper g with a weak result type ([3.3]). The effect of g(u1, u2, ..., uM) shall

be INVOKE (f, v1, v2, ..., vN, result_of<F cv (V1, V2, ..., VN)>::type), where cv represents

the cv-qualifiers of g and the values and types of the bound arguments v1, v2, ..., vN are determined as

specified below.

template<class R, class F, class T1, class T2, ...., class TN>

unspecified bind(F f, T1 t1, T2 t2, ..., TN tN);

3 Requires: F and Ti shall be CopyConstructible. INVOKE (f, w1, w2, ..., wN) shall be a valid expression for

some values w1, w2, ..., wN.

4 Returns: A forwarding call wrapper g with a nested type result_type defined as a synonym for R. The effect of

g(u1, u2, ..., uM) shall be INVOKE (f, v1, v2, ..., vN, R), where the values and types of the bound

arguments v1, v2, ..., vN are determined as specified below.

5 The values of the bound arguments v1, v2, ..., vN and their corresponding types V1, V2, ..., VN depend on

the type of the corresponding argument ti of type Ti in the call to bind and the cv-qualifiers cv of the call wrapper g as

follows:

— if ti is of type reference_wrapper<T> the argument is ti.get() and its type Vi is T&;

— if the value of std::tr1::is_bind_expression<Ti>::value is true the argument is ti(u1, u2, ...,

uM) and its type Vi is result_of<Ti cv (U1&, U2&, ..., UM&)>::type;

— if the value j of std::tr1::is_placeholder<Ti>::value is not zero the argument is uj and its type Vi is

Uj&;

— otherwise the value is ti and its type Vi is Ti cv &. 

這里參數t,v,W來回出現,挺繞的,書讀百遍,其義自現 f為要綁定的函數,其參數為 v1,v2,…,vN,類型為V1,V2,…,VN

bind 函數參數為t1, t2, …,tN,類型為T1,T2,…,TN

g 為bind的返回值,參數為參數為u1, u2,…uM,類型為U1, U2,…,UM.

g(u1, u2,…uM)會被轉發給f,轉發效果相當于f(v1, v2, …,vN)

vi 如下確定

如果對應bind函數參數ti類型為reference_wrapper<T>, 則vi為ti.get(),類型為T&
如果std::tr1::is_bind_expression<Ti>::value為true,即ti是bind的返回值,則vi為ti(u1,u2,…uM),類型為result_of<Ti cv(U1&,U2&,…,UM)>::type
如果std::tr1::is_placeholder<Ti>::value非0,則參數vi為uj,類型為 Uj&
否則vi值為ti,類型為Ti cv& 

現在就很明了了,一個bind的返回值r1可以作為另一個bind的參數a1,在轉發時轉發的是r1(u1, u2,…,uM),即測試的代碼是符合標準的.那為什么通不過呢?再加上兩個測試,看看bind的返回值類型究竟能否讓 is_bind_expression<T>::value為true

is_bind_expression測試

  1. template<class T>  
  2. bool IsBindResult(const T& v)  
  3. {  
  4. return std::tr1::is_bind_expression<T>::value;  
  5. }  
  6. TEST(IsBindResult, BindFuncPtr)  
  7. {  
  8. ASSERT_TRUE(IsBindResult(std::tr1::bind(Add, std::tr1::placeholders::_1, 2)));  
  9. }  
  10. TEST(IsBindResult, BindFunctor)  
  11. {  
  12. ASSERT_TRUE(IsBindResult(std::tr1::bind(std::plus<int>(), std::tr1::placeholders::_1, 2)));  

編譯,運行

clip_image001

結果再次讓偶大躍眼鏡,居然bind的返回值沒能通過is_bind_expression的測試,怎么回事,打開is_bind_expression 的源碼來看

is_bind_expression定義

  1. template<class _Tx>  
  2. struct is_bind_expression  
  3. {   
  4. static const bool value = false;  
  5. };  
  6. template<class _Result_type,  
  7. class _Ret,  
  8. class _BindN>  
  9. struct is_bind_expression<  
  10. _Bind<_Result_type, _Ret, _BindN> >  
  11. {   
  12. static const bool value = true;  
  13. }; 

這里對模板作了一個特化,如果bind的模板參數是 _Bind<_Result_type, _Ret, _BindN>類型,則value為true,否則false.

看上去很美,沒問題,那為什么測試會失敗?難道bind(Add,…)返回的是_Bind類型而 bind(plus<int>(),…)返回的不是?接著看bind實現:

函數指針版

bind到函數指針的返回類型

  1. template<class _Rx  
  2. _C_CLASS_FARG0  
  3. _C_CLASS_ARG0> inline  
  4. _Bind<_Rx,  
  5. _Rx,  
  6. _BINDN<_Callable_fun<_Rx(__cdecl * const)(_FARG0_FARG1)> _C_ARG0_ARG1> >  
  7. bind(_Rx(__cdecl * const _Val)(_FARG0_FARG1) _C_ARG0_A0)  
  8. // bind to pointer to function  
  9. typedef _Callable_fun<_Rx(__cdecl * const)(_FARG0_FARG1)> _Callable;  
  10. typedef _BINDN<_Callable _C_ARG0_ARG1> _MyBind;  
  11. return (_Bind<_Rx, _Rx, _MyBind>(_MyBind(_Val _C_A0_A1)));  

返回的的確是_Bind類型,

仿函數版

bind到仿函數的返回類型

  1. template<class _Fty  
  2. _C_CLASS_ARG0> inline  
  3. _Bind_fty<_Fty,  
  4. _Notforced,  
  5. _BINDN<_Callable_obj<_Fty> _C_ARG0_ARG1> >  
  6. bind(_Fty _Val _C_ARG0_A0)  
  7. // bind to UDT  
  8. typedef _BINDN<_Callable_obj<_Fty> _C_ARG0_ARG1> _MyBind;  
  9. return (_Bind_fty<_Fty, _Notforced, _MyBind>(_MyBind(_Val _C_A0_A1)));  

返回的卻是_Bind_fty類型, 難道_Bind_fty不是_Bind類型導致is_bind_expression返回false?接著看定義

_BindN和_Bind_fty的定義

  1. template<class _Ret,  
  2. class _BindN>  
  3. class _Bind<_Notforced, _Ret, _BindN>  
  4. public _Bind_base<_Ret, _BindN>  
  5. {   
  6. public:  
  7. _Bind(_BindN _B0)  
  8. : _Bind_base<_Ret, _BindN>(_B0)  
  9. {   
  10. }  
  11. };  
  12. template<class _Fty,  
  13. class _Ret,  
  14. class _BindN>  
  15. class _Bind_fty  
  16. public _Wrap_result_type<(sizeof (::std:: tr1::_Has_result_type((_Fty *)0)) == sizeof (::std:: tr1::_Yes)), _Fty>,  
  17. public _Bind_base<_Ret, _BindN>  
  18. {   
  19. public:  
  20. _Bind_fty(_BindN _B0)  
  21. : _Bind_base<_Ret, _BindN>(_B0)  
  22. {   
  23. }  
  24. }; 

果然如此,真相大白.is_bind_expression不認為 bind(functor…)是bind表達式,故會直接將其作為類型為_Bind_fty的參數轉發為 logical_and,導致編譯出錯.

找到錯誤原因,可以開bug了 Title: std::tr1::bind can't bind a functor as an argument to another functor

How found: manual test

Build version:VC 1010 01019-532-2002102-70993

OS: Windows XP

Repro steps:

Run following code:

出錯代碼

  1. TEST(Bind, Squarediff_Functorptr)  
  2. {  
  3. auto f0 = std::tr1::bind(std::multiplies<int>(),  
  4. std::tr1::bind(std::plus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2),  
  5. std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2));  
  6. ASSERT_EQ(16, f0(5, 3));  
  7. }  
  8. Expected:  
  9. Code got compiled and test passed. See n1836  
  10. Result:  
  11. Build break 
  12.  
  13. Note:  
  14.  
  15. The result of std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2) 
  16. is of type _Bind_fty, which will make is_bind_expression<_Bind_fty>::value = false. Suggestion: modify the 
  17. return type of bind or change is_bind_expression to make is_bind_expression<_Bind_fty>::value to be true.  

提交bug, Ok.

結束了么?還沒有,需要編寫一個測試來驗證這個問題并加到測試列表里去,可是直接寫會導致編譯出錯,怎么辦呢?

有辦法,

將如下代碼保存到一個文件去

測試代碼

  1. #include <iostream>  
  2. #include <conio.h>   
  3. #include <tchar.h>  
  4. int main()   
  5. {   
  6. auto f0 = std::tr1::bind(std::multiplies&lt;int&gt;(),   
  7. std::tr1::bind(std::plus&lt;int&gt;(), std::tr1::placeholders::_1, std::tr1::placeholders::_2),   
  8. std::tr1::bind(std::minus&lt;int&gt;(), std::tr1::placeholders::_1, std::tr1::placeholders::_2));   
  9. return f0(5, 3);   

調用cl編譯這個文件,如果能得到一個可執行程序并且執行后返回16則測試通過,否則測試失敗.

代碼就不在這里列舉了.

寫完測試,添加到daily build的test list中去,什么時候問題解決了從測試結果上就能看出來了.

1 文中寫的找bug的過程是直線式的邏輯,思路很清晰,實際我在跟代碼的時候就像在一個迷宮里打轉,只看見出了錯誤,不知道什么地方錯了,只好用各種手段, 想先找出bind在綁定函數指針時究竟干了什么,再來推理為什么綁定仿函數會出錯,根本不是象文中寫的那 樣直接推斷到is_bind_expression的問題.

VC2010里tr1庫的實現實在不好閱讀,滿篇全是宏,連函數調用傳了幾個參數都搞不清楚,我只好先用/E選項把預編譯的文件輸出出來,在跟蹤代碼時一邊看預處理后的代碼一邊看匯編,無論哪個都比tr1自己的源代碼好讀.

不過這一番跟蹤下來收獲倒也頗豐,

1) 基本清楚了bind的實現,可以另外寫篇博客來談

2) 明白了RVO(返回值優化)的原理.在跟蹤bind匯編代碼時時發現只要三個參數,卻push了四個,調用完成后也是ret 10返回,跟了下去才發現是做的RVO

2 文中用到了ASSERT宏進行測試,也算是對前些天對我這篇金山衛士代碼批評評論里大家對ASSERT質疑的一個回應吧.c++庫里的assert的作用是及時發現錯誤反饋給程序員, 會打斷程序執行,而測試框架里的ASSERT則是斷言測試是否符合預期,把結果傳遞給測試框架,再由測試框架記錄后反饋給程序員.我原來以為在那個上下文都是測試情況下assert的語義應當不言自明的是指后者,沒想到還是有很多讀者誤以為是c++庫里的assert.這是我沒有把話說清楚,假定自己知道的受眾也知道,忽略了背景的區別帶來的對同一個名詞不同的理解,是我經常犯的一個錯誤,要努力改正.

3 QA除了寫測試用例,用工具和腳本進行測試外還可以在項目過程中參與更多.一個好的QA應當有不弱于Dev的編碼能力, 有能力復查Dev設計和編碼,直接從中發現問題,以及在測試中發現問題時有能力定位bug源頭并給出參考解決方案.QA還要有縝密的思維和想象能力,對邊界條件、各種邏輯組合和極端情況能去構造和評估其對功能的影響,因為Dev一般習慣于正常情況下的邏輯,邊界情況雖然也會考慮,但還是不會有QA想的全面.遺憾的是目前國內開發團隊中這樣的QA還是比較少見.

原文鏈接:http://www.cnblogs.com/MichaelPeng/archive/2010/12/27/ABugReportOnVC2010_std_tr1_bind.html

【編輯推薦】 

  1. Visual Studio自定義調整窗體的兩個小技巧
  2. Visual Studio 2010中關于C#的幾點改進
  3. Visual Studio 2010及.Net 4新功能一覽
  4. 提高效率 用好Visual Studio 2010自定義代碼段
     

 

責任編輯:彭凡 來源: 博客園
相關推薦

2011-08-16 14:50:05

CMFCToolBarVS2010

2009-12-02 14:19:09

VS 2010產品

2011-06-23 10:16:55

VS2010 QT 4.7.2 QT

2009-11-11 11:29:37

VS2010 Auto

2009-12-11 15:13:15

VS 2010驅動

2009-07-28 10:00:47

VS2010 beta

2010-01-14 10:56:43

Visual C++

2009-12-15 17:55:54

VS2010 Ulti

2009-12-11 14:16:11

VS2010 Ulti

2009-12-15 17:42:29

2011-01-18 08:55:20

IntelliTracVS2010

2009-12-02 14:05:17

VS2010程序

2010-04-18 19:51:03

VS2010

2009-12-18 10:24:28

VS 2010代碼

2010-05-06 17:46:47

2009-05-26 10:01:51

Visual StudVisual C++C++0x

2009-06-10 22:41:47

Visual StudVS2010ASP.NET MVC

2011-06-23 09:54:00

VS2010 Qt 4.7.2 Qt

2009-05-21 14:42:09

.NET 4.0VS2010Visual Stud

2010-12-01 13:21:32

TechED2010
點贊
收藏

51CTO技術棧公眾號

91国内精品久久久| 久久精品在线观看视频| 黑人巨大精品| 中文一区二区完整视频在线观看| 91视频国产精品| 久久久久久久久久综合| 夜夜春成人影院| 在线播放中文一区| 国产97在线 | 亚洲| 亚洲麻豆精品| 91丝袜美腿高跟国产极品老师| 国产精品美腿一区在线看| 永久免费看黄网站| 国产精品嫩草影院在线看| 日韩一区二区免费高清| 欧美日韩一区二区在线免费观看| 久久99精品久久久久久野外| 99精品视频在线观看免费| 国产欧美在线视频| 久久久久久少妇| 夜间精品视频| 永久免费看mv网站入口亚洲| 一本加勒比波多野结衣| 亚洲欧美久久精品| 欧美性猛片xxxx免费看久爱 | 97精品97| 亚洲日韩第一页| 黄色av网址在线观看| 精品成人18| 欧美色图12p| 国产97色在线 | 日韩| bl在线肉h视频大尺度| 亚洲免费在线看| 亚洲一区尤物| 国产高清视频在线| www欧美成人18+| 国产一区二区三区av在线| www.天堂在线| 美女视频免费一区| 国产精品电影网站| 亚洲 欧美 中文字幕| 99在线观看免费视频精品观看| 精品中文字幕乱| 91在线播放观看| 天天做综合网| 久久手机精品视频| 大地资源高清在线视频观看| 日韩久久精品| 亚洲性视频网站| 少妇大叫太粗太大爽一区二区| 卡通动漫精品一区二区三区| 亚洲精品在线免费播放| 人妻精油按摩bd高清中文字幕| 国产va免费精品观看精品| 欧美日韩精品福利| 狠狠干狠狠操视频| 综合久草视频| 日韩欧美一卡二卡| 五月天丁香社区| 精品国内亚洲2022精品成人| 日韩精品黄色网| 37p粉嫩大胆色噜噜噜| 亚洲区小说区图片区qvod按摩| 欧美一级欧美一级在线播放| 国产ts在线观看| 久久porn| 国产一区二区三区在线观看网站| 欧美波霸videosex极品| 天天做天天爱天天综合网| 久久99久久99精品免观看粉嫩| 精品一区二区三区人妻| 一本色道久久综合亚洲精品高清| 日本精品性网站在线观看| 91丨九色丨海角社区| 极品尤物av久久免费看| 成人3d动漫一区二区三区91| 熟妇人妻av无码一区二区三区| 久久女同性恋中文字幕| 亚洲欧美成人一区| 羞羞的视频在线看| 岛国视频午夜一区免费在线观看| wwwwww.色| 日本精品在线播放| 亚洲国产毛片完整版| 亚洲а∨天堂久久精品2021| 99re66热这里只有精品8| 欧美激情一区二区三级高清视频| 亚洲欧美综合另类| 激情五月激情综合网| 国产精品二区二区三区| 麻豆导航在线观看| 亚洲精品视频在线| 虎白女粉嫩尤物福利视频| 亚洲色图综合| 日韩精品视频观看| 国产尤物在线播放| 在线亚洲激情| 91在线观看免费观看| 桃花色综合影院| 亚洲欧洲精品一区二区精品久久久 | 亚洲色图都市小说| 国产精品裸体瑜伽视频| 欧美伊人亚洲伊人色综合动图| 亚洲国产天堂久久综合| 国产一区二区三区视频播放| 99在线观看免费视频精品观看| 成人精品一区二区三区电影免费| 亚洲欧美日韩精品永久在线| 亚洲婷婷国产精品电影人久久| 日韩av黄色网址| 日韩精品视频一区二区三区| 一区二区三区www| 日韩欧美一区二区一幕| 国产在线国偷精品产拍免费yy| 免费国产在线精品一区二区三区| 色呦呦在线看| 欧美麻豆精品久久久久久| 在线观看日韩精品视频| 国产综合自拍| 亚洲在线第一页| 在线观看黄av| 色狠狠av一区二区三区| a天堂视频在线观看| 中文字幕日韩一区二区不卡 | 在线免费av网| 久久久久久久综合狠狠综合| 欧洲精品一区二区三区久久| 日韩欧美一级| 久久天天躁狠狠躁夜夜躁2014| 中国老头性行为xxxx| 久久看人人爽人人| 尤物av无码色av无码| 亚洲一区二区免费在线观看| 另类少妇人与禽zozz0性伦| 中文字幕有码无码人妻av蜜桃| 91网站视频在线观看| 国产中文字幕二区| 欧美三级午夜理伦三级小说| 欧美劲爆第一页| 不卡视频在线播放| 亚洲综合图片区| 无码人妻一区二区三区精品视频| 亚洲情侣在线| 亚洲自拍偷拍网址| 最新黄网在线观看| 欧美一区二区三区系列电影| 欧美色图亚洲视频| 国产成人av资源| 日b视频免费观看| 中文在线综合| 91国内在线视频| 五月婷婷六月丁香| 色综合久久久久网| 影音先锋制服丝袜| 麻豆精品视频在线观看| 在线国产精品网| 国产精品视频首页| 久久久欧美精品| 青青草在线免费视频| 色婷婷精品大视频在线蜜桃视频| 性少妇bbw张开| 日本免费在线视频不卡一不卡二| 亚洲乱码一区二区三区| 国产午夜亚洲精品一级在线| 欧美黑人xxxx| 日韩a在线观看| 色999日韩国产欧美一区二区| 青青青视频在线免费观看| 激情成人午夜视频| 日本免费a视频| 任我爽精品视频在线播放| 日本亚洲精品在线观看| 午夜看片在线免费| 日韩欧美国产wwwww| 91蜜桃视频在线观看| 国产午夜精品美女毛片视频| 中文字幕精品一区二区三区在线| 中文字幕一区二区三区乱码图片| 国产自产精品| 国产精品久久乐| 欧美xxxx做受欧美.88| 日本美女一级片| 欧美在线你懂的| 精品99久久久久成人网站免费 | 亚洲天堂一级片| 成人在线视频一区二区| 熟女人妇 成熟妇女系列视频| 婷婷综合伊人| 久久久久无码国产精品一区| 久久亚洲精品中文字幕| 欧美激情在线观看视频| 久草在现在线| 精品欧美黑人一区二区三区| 婷婷激情五月综合| 一区二区欧美在线观看| 欧洲美熟女乱又伦| 国产宾馆实践打屁股91| 无码人妻丰满熟妇区毛片| 亚洲区综合中文字幕日日| 欧美三级网色| 国产一区丝袜| 成人精品在线视频| 久久野战av| 久久久久久久久久国产精品| 日本免费中文字幕在线| 亚洲精品美女免费| 亚洲a视频在线| 欧美日韩国产小视频在线观看| 免费看日韩毛片| 亚洲女子a中天字幕| 少妇精品无码一区二区免费视频| av欧美精品.com| 中文字幕av一区二区三区人妻少妇| 日韩中文字幕麻豆| 国内精品在线观看视频| 外国成人激情视频| 神马一区二区影院| 亚洲电影一级片| 国产嫩草一区二区三区在线观看 | 视频精品一区二区| www.av片| 欧美午夜免费影院| 国产高潮呻吟久久久| 成人影视亚洲图片在线| 久久精品日韩精品| 日韩美脚连裤袜丝袜在线| 97人人澡人人爽| 国产精品一区二区精品| 国产精品一区二区女厕厕| 欧美日韩在线观看首页| 午夜精品久久久久久久久久久久| 免费不卡av| 欧美成人在线免费| 91国内在线| 成人444kkkk在线观看| 免费在线视频欧美| 色偷偷9999www| av电影在线观看| 在线精品国产成人综合| 国产无套粉嫩白浆在线2022年| 亚洲国产日韩欧美在线图片| 日韩一级片免费看| 亚洲成人国产精品| 天堂av手机版| 日韩精品视频中文在线观看| 天天干天天干天天干| 亚洲精品电影网站| 亚洲日本国产精品| 亚洲欧美日韩一区在线| 欧美一区二区视频| 亚洲欧洲自拍偷拍| 69久久夜色| www.日韩.com| 日韩专区av| 97在线精品国自产拍中文| 性欧美ⅴideo另类hd| 久久久久久久久久国产| 英国三级经典在线观看| 国产成人激情小视频| 超碰这里只有精品| 成人欧美一区二区三区在线 | 国产三级电影在线播放| 欧洲日本亚洲国产区| 深夜视频一区二区| 成人夜晚看av| 都市激情亚洲| 欧美日韩精品一区| 色小子综合网| 免费看日本黄色| 亚洲免费中文| 在线免费视频a| 国产精品亚洲一区二区三区妖精| 久久久久亚洲AV成人网人人小说| 91在线视频观看| 久久国产柳州莫菁门| 亚洲欧美国产高清| 欧美三级韩国三级日本三斤在线观看| 91福利精品视频| av网站免费大全| 精品亚洲一区二区三区四区五区| h网站在线免费观看| 欧美成人一区在线| 亚洲成人看片| 成人18视频| 青草国产精品| 国产一级做a爰片久久毛片男| 亚欧成人精品| 樱花草www在线| 26uuu精品一区二区| 暗呦丨小u女国产精品| 亚洲成av人综合在线观看| 艳妇乳肉豪妇荡乳av无码福利| 欧美一区二区视频网站| 亚洲av成人精品一区二区三区在线播放| 国产亚洲欧洲在线| av今日在线| 96sao精品视频在线观看| 亚洲小说图片视频| 99热这里只有精品免费| 日韩精品国产欧美| 水蜜桃av无码| 亚洲精品乱码久久久久久黑人| 欧美特黄aaaaaa| 欧美一级一区二区| 高清日韩av电影| 97在线观看视频国产| 免费观看亚洲视频大全| 亚洲精品一品区二品区三品区| 亚洲少妇诱惑| www.黄色网| 中文字幕永久在线不卡| 国产污视频网站| 精品999久久久| а天堂中文在线官网| 国产精品国产福利国产秒拍| 欧美亚洲大陆| 国产精品第157页| 国产一区在线精品| 在线观看免费黄色网址| 日本精品一级二级| 天堂av资源在线| 久久久久中文字幕2018| 麻豆久久一区| 日本一道在线观看| 激情偷乱视频一区二区三区| 亚洲色成人网站www永久四虎| 精品久久香蕉国产线看观看亚洲| 超碰在线播放97| 九九久久综合网站| 国产成人久久精品一区二区三区| 亚洲欧美国产不卡| 久久99久久久欧美国产| 欧美激情久久久久久久| 欧洲av一区二区嗯嗯嗯啊| 三级无遮挡在线观看| 69视频在线播放| 美国十次av导航亚洲入口| 国产一区二区四区| 成人在线综合网| 中日韩精品视频在线观看| 精品久久一区二区| 黄网在线免费看| 国产精品美女诱惑| 最新日韩在线| 精品少妇一区二区三区免费观 | 一卡二卡三卡在线| 综合欧美国产视频二区| 日韩综合av| 中文字幕在线中文字幕日亚韩一区 | 成人h动漫精品一区二区无码| 欧美成人午夜激情视频| 91亚洲精品视频在线观看| www.射射射| 久久亚洲精品小早川怜子| 国产一级一级国产| 伊人伊成久久人综合网站| 欧美黑粗硬大| 久久久国内精品| 97久久超碰国产精品电影| 午夜影院免费在线观看| 原创国产精品91| 电影一区中文字幕| 日本丰满少妇xxxx| 久久美女高清视频| 中文字幕第三页| 欧美成人免费va影院高清| 哺乳挤奶一区二区三区免费看 | 久久国产成人午夜av影院| 丁香花五月激情| 日韩av影视综合网| 中文.日本.精品| 日韩人妻一区二区三区蜜桃视频| 懂色av噜噜一区二区三区av| 日韩欧美成人一区二区三区| 中文字幕欧美亚洲| 综合中文字幕| 任你操这里只有精品| 亚洲色图制服诱惑| 五月激情丁香婷婷| 国产欧美一区二区| 伊人影院久久| 精品人体无码一区二区三区| 日韩欧美国产午夜精品| 亚洲永久av| 强开小嫩苞一区二区三区网站| www.成人网.com| 国产精品乱码一区二区| 国产91精品不卡视频| 日韩综合在线| 美女又爽又黄免费| 欧美浪妇xxxx高跟鞋交| 理论不卡电影大全神| 一区二区视频在线免费| www.亚洲色图| 国产毛片在线视频| 日韩美女av在线免费观看| 欧美精品三级| 中文字幕91视频| 亚洲精品天天看| 亚洲小说春色综合另类电影|